00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00031
00032
00033
00034
00035 #ifdef __GNUG__
00036 #pragma implementation "Number.h"
00037 #endif
00038
00039
00040 #include "mc/mcprec.h"
00041 #ifdef __BORLANDC__
00042 #pragma hdrstop
00043 #endif
00044
00045 #ifndef mcPRECOMP
00046 #include <wx/dcscreen.h>
00047 #include "mc/MathCore.h"
00048 #include "mc/Number.h"
00049 #include "mc/Monomial.h"
00050 #include "mc/Fraction.h"
00051 #endif
00052
00053
00054
00055 mcIMPLEMENT_MAIN_CLASS(mcNumber, mcExpElement);
00056
00057
00058
00059 mcNumber *mcNumberHelpers::smath_pOne = NULL;
00060 mcNumber *mcNumberHelpers::smath_pTwo = NULL;
00061 mcNumber *mcNumberHelpers::smath_pFour = NULL;
00062 mcNumber *mcNumberHelpers::smath_pMinusOne = NULL;
00063 mcNumber *mcNumberHelpers::smath_pZero = NULL;
00064
00065 wxString mcNumberHelpers::sgui_strFloatingPoint = wxT(".,");
00066 int mcNumberHelpers::sgui_nDigitToShow = -1;
00067 bool mcNumberHelpers::smath_bUseIntegersWhenPossible = TRUE;
00068
00069
00070
00071 mcNumber mcEmptyNumber(NULL);
00072
00073
00074
00075
00076
00077
00078
00079 mcFraction mcNumber::math_TransformInFraction()
00080 { return hlp()->math_TransformInFraction(); }
00081
00082
00083
00084
00085
00086
00087
00088
00089 bool mcNumberHelpers::gui_isDigit(int c) {
00090 switch (c) {
00091 case wxT('0'): case wxT('1'):
00092 case wxT('2'): case wxT('3'):
00093 case wxT('4'): case wxT('5'):
00094 case wxT('6'): case wxT('7'):
00095 case wxT('8'): case wxT('9'):
00096 return TRUE;
00097 }
00098 return FALSE;
00099 }
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 bool mcNumberHelpers::gui_isBeginKey(const mcKey &ev) const
00137 {
00138 if (mcNumberHelpers::gui_isDigit(ev.GetKeyCode()) && ev.GetModifiers() == 0)
00139 return TRUE;
00140 return FALSE;
00141 }
00142
00143 bool mcNumberHelpers::gui_isBaseEndKey(const mcKey &ev) const
00144 {
00145
00146
00147 if (mcNumberHelpers::gui_isDigit(ev.GetKeyCode()) ||
00148 mcNumberHelpers::gui_isDecimalPoint(ev.GetKeyCode()) ||
00149 mcMathCore::Get()->MatchEditKeys(ev))
00150 return FALSE;
00151 return TRUE;
00152 }
00153
00154 void mcNumberHelpers::gui_DoRecalcBaseSize()
00155 {
00156 wxString tmp = gui_GetStr();
00157
00158
00159 wxScreenDC dc;
00160 gui_SelectStyle(dc);
00161 mgui_szBase = gui_GetSizeOf(&dc, tmp);
00162 }
00163
00164 int mcNumberHelpers::gui_DrawBase(wxDC &hDC, int x, int y, long flags,
00165 const wxPoint &pt) const
00166 {
00167 mcGUILOG(wxT("mcNumberHelpers::gui_DrawBase"));
00168 wxString tmp = gui_GetStr();
00169
00170 if (!(flags & mcDRW_NONACTIVE)) {
00171
00172
00173
00174 hDC.SetBrush(*mcElementHelpers::sgui_pActivationBrush);
00175 hDC.SetPen(*wxBLACK_PEN);
00176 hDC.DrawRectangle(x-sgui_nAdditionalActivationSpaceLeftRight, y,
00177 gui_GetBaseSize().GetWidth()+sgui_nAdditionalActivationSpaceLeftRight*2,
00178 gui_GetBaseSize().GetHeight());
00179 }
00180
00181
00182 gui_SelectStyle(hDC);
00183 hDC.SetBackgroundMode(wxTRANSPARENT);
00184 hDC.DrawText(tmp, x, y);
00185
00186 return data_GetID();
00187 }
00188
00189 void mcNumberHelpers::gui_EditBase()
00190 {
00191
00192 mgui_nCursorPos = data_Get().GetNumOfDigits();
00193 mgui_nCursorLoc = mcECL_INSIDEBASE;
00194 }
00195
00196 void mcNumberHelpers::gui_Set(const wxString &str)
00197 {
00198 wxString n = str;
00199
00200
00201 while (n.GetChar(0) == wxT('0')) {
00202
00203
00204 n.Remove(0, 1);
00205 mgui_nCursorPos--;
00206
00207
00208 if (n.Len() == 1)
00209 break;
00210 }
00211
00212
00213 mgui_strTrailer = wxT("");
00214 data_Set(n);
00215
00216
00217 int len = gui_GetStr().Len();
00218 if (len < (int)n.Len())
00219 mgui_strTrailer = n.Right(n.Len()-len);
00220 }
00221
00222 mcInputRes mcNumberHelpers::gui_BaseInput(const mcKey &key, mcElement *pnew)
00223 {
00224
00225 if (gui_HandleSubExpEditKeys(key) == mcIR_OKAY)
00226 return mcIR_OKAY;
00227
00228
00229 if (mcMathCore::Get()->m_pDeleteKey->MatchKey(key)) {
00230
00231 if (mgui_nCursorPos == 0) {
00232
00233
00234 return mcIR_DELETE_PREVIOUS;
00235 }
00236
00237 if (mgui_nCursorPos == 1 && data_Get().GetNumOfDigits() == 1) {
00238
00239
00240 return mcIR_DELETE_THIS;
00241 }
00242
00243
00244 wxString str = gui_GetStr();
00245 str.Remove(mgui_nCursorPos-1, 1);
00246 gui_Set(str);
00247
00248
00249 mgui_nCursorPos--;
00250
00251 } else if (mcMathCore::Get()->m_pCancelKey->MatchKey(key)) {
00252
00253 if (mgui_nCursorPos == data_Get().GetNumOfDigits()) {
00254
00255
00256 return mcIR_DELETE_NEXT;
00257 }
00258
00259 if (mgui_nCursorPos == 0 && data_Get().GetNumOfDigits() == 1) {
00260
00261
00262 return mcIR_DELETE_THIS;
00263 }
00264
00265
00266 wxString str = gui_GetStr();
00267 str.Remove(mgui_nCursorPos, 1);
00268 gui_Set(str);
00269
00270
00271
00272 } else if (mcNumberHelpers::gui_isDigit(key.GetKeyCode())) {
00273
00274
00275 if (data_Get() == 0 && mgui_nCursorPos == 0) mgui_nCursorPos++;
00276
00277
00278 wxString str = gui_GetStr();
00279 str = str.Left(mgui_nCursorPos) + key.GetKeyCode() +
00280 str.Right(str.Len()-mgui_nCursorPos);
00281 mgui_nCursorPos++;
00282
00283
00284 gui_Set(str);
00285
00286 } else if (mcNumberHelpers::gui_isDecimalPoint(key.GetKeyCode())) {
00287
00288
00289 if (!data_Get().isInteger()) {
00290 mcMathCore::Get()->SyntaxError(wxT("Cannot insert another decimal point !!!"));
00291 return mcIR_OKAY;
00292 }
00293
00294
00295
00296 mgui_strTrailer = mcNUMBER_DECIMAL_POINT;
00297 mgui_nCursorPos++;
00298 }
00299
00300
00301 gui_RecalcSize();
00302
00303 return mcIR_OKAY;
00304 }
00305
00306 mcInsertRes mcNumberHelpers::gui_BaseInsert(const mcElement &toinsert, mcElement *newelem)
00307 {
00308
00309
00310 return mcINSR_OKAY;
00311 }
00312
00313 bool mcNumberHelpers::gui_Split(mcElement *p)
00314 {
00315 bool b = FALSE;
00316
00317
00318
00319
00320
00321
00322 mcNumber pnew;
00323
00324
00325
00326 pnew.data_Set(data_Get().GetFromDigitRange(mgui_nCursorPos, -1));
00327 this->data_Set(data_Get().GetFromDigitRange(0, mgui_nCursorPos));
00328
00329 pnew.gui_RecalcSize();
00330 gui_RecalcSize();
00331
00332
00333
00334 if (this->data_Get() == 0)
00335 b = TRUE;
00336
00337 *p = pnew;
00338 if (pnew.data_Get() == 0)
00339 *p = NULL;
00340
00341 return b;
00342 }
00343
00344 bool mcNumberHelpers::gui_MergeWith(const mcElement &p)
00345 {
00346 if (p.data_GetType() != mcET_NUMBER)
00347 return FALSE;
00348
00349 mcNumber n(p);
00350 int len = n.data_Get().GetNumOfDigits();
00351
00352
00353 mcRealValue res = data_Get()*mcRealValue(10).pow(len) + n.data_Get();
00354 data_Set(res);
00355
00356
00357 gui_RecalcSize();
00358
00359
00360 return TRUE;
00361 }
00362
00363 mcMoveCursorRes mcNumberHelpers::gui_BaseMoveCursor(mcMoveCursorFlag flag, long modifiers)
00364 {
00365 int n;
00366
00367
00368 if (flag == mcMCF_UP)
00369 return mcMCR_SETFOCUS_ABOVE;
00370 if (flag == mcMCF_DOWN)
00371 return mcMCR_SETFOCUS_BELOW;
00372
00373 switch (flag) {
00374 case mcMCF_LEFT:
00375
00376 if (mgui_nCursorPos > 0) {
00377
00378
00379 mgui_nCursorPos--;
00380
00381 } else if (mgui_nCursorPos == 0) {
00382
00383
00384
00385 return mcMCR_SETFOCUS_PREVIOUS;
00386 }
00387 break;
00388
00389 case mcMCF_RIGHT:
00390 n = data_Get().GetNumOfDigits();
00391
00392 if (mgui_nCursorPos < n) {
00393
00394
00395 mgui_nCursorPos++;
00396
00397 } else {
00398
00399
00400
00401
00402 return mcMCR_SETFOCUS_NEXT;
00403 }
00404 break;
00405
00406 case mcMCF_UP:
00407 case mcMCF_DOWN:
00408 break;
00409 }
00410
00411
00412 return mcMCR_OKAY;
00413 }
00414
00415 int mcNumberHelpers::gui_BaseMoveCursorUsingPoint(wxDC &hDC, const wxPoint &pt)
00416 {
00417 int w, h, r, n;
00418 wxRect rc;
00419
00420
00421 mcASSERT(pt.x > 0 && pt.y > 0, wxT("Invalid pointer"));
00422
00423
00424 w = gui_GetWidthOfChar(&hDC, this);
00425 h = gui_GetHeightOfChar(&hDC, this);
00426 r = data_Get().GetNumOfDigits();
00427
00428 for (n=0; n < r; n++) {
00429
00430
00431 rc.x = n*w;
00432 rc.width = w;
00433 rc.y = 0;
00434 rc.height = h;
00435
00436 if (rc.Inside(pt)) {
00437
00438
00439 rc.width /= 2;
00440 if (rc.Inside(pt))
00441 mgui_nCursorPos = n;
00442 else
00443 mgui_nCursorPos = n+1;
00444 }
00445 }
00446
00447 return mcMCR_OKAY;
00448 }
00449
00450 int mcNumberHelpers::gui_GetBaseRelCursorPos(wxDC &hDC, wxPoint *pt) const
00451 {
00452 wxString tmp = gui_GetStr();
00453 int n;
00454
00455
00456
00457 tmp = tmp.Left(mgui_nCursorPos);
00458
00459
00460
00461 gui_SelectStyle(hDC);
00462 pt->x = gui_GetWidthOf(&hDC, tmp);
00463 pt->y = 0;
00464
00465
00466
00467
00468 n = ((tmp.Length() == 0) ?
00469 gui_GetHeightOfChar(&hDC, this) :
00470 gui_GetHeightOf(&hDC, tmp));
00471
00472 return n;
00473 }
00474
00475 void mcNumberHelpers::gui_GetBaseCursorPos(mcCursorPos &cp) const
00476 {
00477
00478
00479 if (mgui_nCursorPos == 0) {
00480 cp.gui_Push(mcCP_BEGIN);
00481 return;
00482 }
00483
00484
00485
00486 if (mgui_nCursorPos == (int)gui_GetStr().Len()) {
00487 cp.gui_Push(mcCP_END);
00488 return;
00489 }
00490
00491
00492 cp.gui_Push(mgui_nCursorPos);
00493 }
00494
00495 void mcNumberHelpers::gui_SetBaseCursorPos(const mcCursorPos &cp)
00496 {
00497 if (cp.isEnd())
00498
00499
00500
00501 mgui_nCursorPos = gui_GetStr().Len();
00502 else if (cp.isBegin())
00503
00504
00505 mgui_nCursorPos = 0;
00506 }
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517 bool mcNumberHelpers::io_isBeginChar(const wxString &str) const
00518 {
00519 if (str.IsNumber() && mcNumberHelpers::gui_isDigit(str.GetChar(0)))
00520 return TRUE;
00521 return FALSE;
00522 }
00523
00524 wxXml2Node mcNumberHelpers::io_GetBaseMathML(bool bGetPresentation) const
00525 {
00526 if (bGetPresentation) {
00527
00528
00529 return wxXml2Node(wxXML_TEXT_NODE, wxXml2EmptyDoc, wxT("mn"),
00530 data_Get().GetExtStr());
00531
00532 } else {
00533
00534
00535 return wxXml2Node(wxXML_TEXT_NODE, wxXml2EmptyDoc, wxT("cn"),
00536 data_Get().GetExtStr());
00537 }
00538 }
00539
00540 wxString mcNumberHelpers::io_GetBaseInlinedExpr() const
00541 {
00542
00543 return data_Get().GetSmartStr();
00544 }
00545
00546 bool mcNumberHelpers::io_ImportPresentationMathML(wxXml2Node tag, wxString &pErr)
00547 {
00548 mcASSERT(tag.GetName() == wxT("mn"), wxT("Error in mcNumberHelpers::io_isBeginTag()"));
00549
00550 if (tag.GetChildren().GetType() != wxXML_TEXT_NODE) {
00551
00552
00553 pErr = wxT("The MathML to import is not valid MathML 2.0\n")
00554 wxT("or there was an error while parsing it.");
00555 return FALSE;
00556 }
00557
00558
00559 data_Set(tag.GetChildren().GetContent());
00560 data_AddProperty(mcEP_INITIALIZED);
00561
00562
00563 return TRUE;
00564 }
00565
00566 bool mcNumberHelpers::io_ImportBaseInlinedExpr(const wxString &str, int *count, wxString &pErr)
00567 {
00568
00569 *count = 0;
00570 for (int i=0; i < (int)str.Len(); i++) {
00571 wxChar c = str.GetChar(i);
00572 if (mcNumberHelpers::gui_isDigit(c) || c == wxT('.') || c == wxT(','))
00573 (*count)++;
00574 else
00575 break;
00576 }
00577
00578 mcASSERT(*count > 0, wxT("There should be at least one digit..."));
00579
00580
00581 data_Set(str.Left(*count));
00582 data_AddProperty(mcEP_INITIALIZED);
00583
00584 return TRUE;
00585 }
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595 bool mcNumberHelpers::math_CanBeAddedWith(const mcElement &p) const
00596 {
00597 if (p.data_GetType() == mcET_NUMBER)
00598 return TRUE;
00599
00600
00601
00602
00603 return FALSE;
00604 }
00605
00606 bool mcNumberHelpers::math_CanBeMultWith(const mcElement &p) const
00607 {
00608
00609
00610 if (data_Get() == 0.0)
00611 return TRUE;
00612 return math_CanBeAddedWith(p);
00613 }
00614
00615 bool mcNumberHelpers::math_CanBeDivBy(const mcElement &p) const
00616 {
00617 if (math_isZero(p)) return FALSE;
00618
00619
00620
00621 if (data_Get() == 0.0)
00622 return TRUE;
00623
00624
00625 if (p.data_GetType() != mcET_NUMBER)
00626 return FALSE;
00627
00628 mcNumber n(p);
00629 if (math_isValid() && n.math_isValid()) {
00630
00631
00632
00633
00634
00635
00636 if (!mcNumberHelpers::smath_bUseIntegersWhenPossible ||
00637 !this->data_Get().isInteger() || !n.data_Get().isInteger())
00638 return TRUE;
00639
00640
00641
00642
00643 mcIntegerValue us = mcIntegerValue(data_Get());
00644 mcIntegerValue it = mcIntegerValue(n.data_Get());
00645 bool areprime = us.isPrimeTo(it);
00646 mcMATHLOG(wxT("mcNumberHelpers::math_CanBeDivBy - checking if %s and %s are prime; gcd is %s, res is %d"),
00647 us.GetStr().c_str(), it.GetStr().c_str(), us.GCD(it).GetStr().c_str(), areprime);
00648
00649 if (areprime)
00650 return FALSE;
00651 return TRUE;
00652 }
00653
00654
00655 return FALSE;
00656 }
00657
00658 mcBasicOpRes mcNumberHelpers::math_Add(const mcElement &p, mcElement *pp, bool add)
00659 {
00660 mcASSERT(p.data_GetType() == mcET_NUMBER, wxT("Error in #math_CanBeAddedWith"));
00661 mcNumber n(p);
00662
00663 if (add)
00664 data_Set(data_Get() + n.data_Get());
00665 else
00666 data_Set(data_Get() - n.data_Get());
00667
00668 mcLOG(wxT("mcNumberHelpers::math_Add - ADDING; res is %s"), mcTXTV(data_Get()));
00669
00670 return mcBOR_REMOVE_OPERAND;
00671 }
00672
00673 mcBasicOpRes mcNumberHelpers::math_MultiplyBaseOnlyBy(const mcElement &p, mcElement *pp)
00674 {
00675
00676 if (data_Get() == 0.0)
00677 return mcBOR_REMOVE_OPERAND;
00678
00679
00680 mcNumber n(p);
00681 mcASSERT(p.data_GetType() == mcET_NUMBER, wxT("Error in #math_CanBeMultWith"));
00682
00683
00684
00685
00686
00687 data_Set(data_Get() * n.data_Get());
00688
00689
00690 if (!data_Get().isInteger() && mcNumberHelpers::smath_bUseIntegersWhenPossible) {
00691
00692 mcIntegerValue n1, n2;
00693 math_GetNumDen(n1, n2);
00694 data_Set(n1);
00695
00696 mcNumber replacement(n2);
00697 (*pp) = replacement;
00698
00699 return mcBOR_REPLACE_OPERAND;
00700 }
00701
00702 return mcBOR_REMOVE_OPERAND;
00703 }
00704
00705 mcBasicOpRes mcNumberHelpers::math_DivideBaseOnlyBy(const mcElement &p, mcElement *pp)
00706 {
00707
00708 if (data_Get() == 0.0)
00709 return mcBOR_REMOVE_OPERAND;
00710
00711
00712 mcNumber n(p);
00713 mcASSERT(!math_isZero(p), wxT("Cannot perform divisions by zero"));
00714 mcASSERT(p.data_GetType() == mcET_NUMBER, wxT("Error in #math_CanBeDivBy"));
00715
00716 mcRealValue res = data_Get() / n.data_Get();
00717
00718
00719 if (!res.isInteger() && mcNumberHelpers::smath_bUseIntegersWhenPossible) {
00720
00721
00722
00723 mcRationalValue rat(data_Get(), n.data_Get());
00724 rat.Canonicalize();
00725
00726
00727 data_Set(rat.GetNum());
00728 mcNumber replacement(rat.GetDen());
00729
00730 mcMATHLOG(wxT("mcNumberHelpers::math_DivideBaseOnlyBy [%s] - dividying by [%s] ")
00731 wxT("trying to preserve this as a fraction (%s/%s)..."), mcTXTTHIS,
00732 mcTXT(p), data_Get().GetStr().c_str(), replacement.data_Get().GetStr().c_str());
00733
00734 (*pp) = replacement;
00735 return mcBOR_REPLACE_OPERAND;
00736
00737 } else {
00738
00739
00740
00741 data_Set(res);
00742 }
00743
00744 return mcBOR_REMOVE_OPERAND;
00745 }
00746
00747 mcBasicOpRes mcNumberHelpers::math_MultiplyBaseBy(const mcElement &p, mcElement *pp)
00748 {
00749
00750 if (data_Get() == 0.0)
00751 return mcBOR_REMOVE_OPERAND;
00752
00753
00754
00755 mcNumber n(p);
00756
00757
00758 mcASSERT(p.data_GetType() == mcET_NUMBER, wxT("Error in #math_CanBeMultWith"));
00759
00760
00761 mcRealValue n1 = this->math_Evaluate();
00762 mcRealValue n2 = n.math_Evaluate();
00763 mcASSERT(n1.isValid() && n2.isValid(), wxT("Error in #math_CanBeMultWith"));
00764
00765
00766 data_Set(n1 * n2);
00767
00768
00769 if (!data_Get().isInteger() && mcNumberHelpers::smath_bUseIntegersWhenPossible) {
00770
00771 mcIntegerValue m1, m2;
00772 math_GetNumDen(m1, m2);
00773 data_Set(m1);
00774
00775 mcNumber replacement(m2);
00776 (*pp) = replacement;
00777
00778 return mcBOR_REPLACE_OPERAND;
00779 }
00780
00781 return mcBOR_REMOVE_OPERAND;
00782 }
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792 bool mcNumberHelpers::math_GetNumDen(mcIntegerValue &num, mcIntegerValue &den)
00793 {
00794
00795 mcRationalValue rat(data_Get());
00796
00797
00798 rat.Canonicalize();
00799
00800 num = rat.GetNum();
00801 den = rat.GetDen();
00802
00803 return TRUE;
00804 }
00805
00806 mcFraction mcNumberHelpers::math_TransformInFraction()
00807 {
00808 mcIntegerValue n, d;
00809 if (!math_GetNumDen(n, d))
00810 return NULL;
00811
00812
00813 mcFraction f;
00814
00815 mcNumber num(n);
00816 mcNumber den(d);
00817
00818 f.data_GetNum().math_WrapSimple(num);
00819 f.data_GetDen().math_WrapSimple(den);
00820
00821 return f;
00822 }
00823
00824 bool mcNumberHelpers::math_isZero(const mcElement &p)
00825 {
00826 if (p.data_GetType() == mcET_NUMBER &&
00827 mcNumber(p).data_Get() == 0.0)
00828 return TRUE;
00829 return FALSE;
00830 }
00831
00832 bool mcNumberHelpers::math_CompareThisOnly(const mcElement &p, long flags) const
00833 {
00834 if (!mcElementHelpers::math_CompareThisOnly(p, flags))
00835 return FALSE;
00836
00837
00838 if (mcNumber(p).data_Get() == data_Get())
00839 return TRUE;
00840 return FALSE;
00841 }
00842
00843 mcExpSimRes mcNumberHelpers::math_SimplifyBase(long flags, mcElement *pnew)
00844 {
00845
00846 if (!data_Get().isInteger() && mcNumberHelpers::smath_bUseIntegersWhenPossible) {
00847
00848 (*pnew) = math_TransformInFraction();
00849 if ((*pnew) == NULL)
00850 return mcESR_DONE;
00851 mcASSERT((*pnew) != mcEmptyElement, wxT("Could not simplify...."));
00852
00853 return mcESR_REPLACE_THIS;
00854 }
00855
00856
00857 return mcESR_DONE;
00858 }
00859
00860 mcExpSimRes mcNumberHelpers::math_SimplifyBaseExp(long flags, mcElement *)
00861 {
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871 mcNumber tmp(this);
00872 mcRealValue exp = tmp.data_GetExp().math_Evaluate();
00873 tmp.data_Set(data_Get().pow(exp));
00874 tmp.data_DestroyExpSub(TRUE);
00875
00876
00877 mcRealValue lenght = tmp.math_GetTotalLenght();
00878
00879
00880
00881 if (math_GetTotalLenght() > lenght) {
00882
00883
00884 mcRealValue exp = data_GetExp().math_Evaluate();
00885 data_Set(data_Get().pow(exp));
00886 data_DestroyExpSub(TRUE);
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897 return mcESR_NOTFINISHED;
00898
00899 } else {
00900
00902
00903
00904
00905
00906
00907
00908
00909 }
00910
00911 return mcESR_DONE;
00912 }
00913
00914 mcExpSimRes mcNumberHelpers::math_ExpandBase(long flags, mcElement *)
00915 {
00916 return mcESR_DONE;
00917
00918
00919
00920
00921
00922
00923 }
00924
00925 mcBasicOpRes mcNumberHelpers::math_MakeReciprocal(mcElement *pp)
00926 {
00927 mcRealValue tmp = data_Get();
00928
00929 mcFraction f;
00930 f.data_SetNum(*mcPolynomialHelpers::smath_pOne);
00931 f.data_GetDen().math_WrapSimple(this);
00932
00933 *pp = f;
00934 return mcBOR_REMOVE_OPERAND;
00935 }
00936
00937 void mcNumberHelpers::math_RaiseBaseTo(mcRealValue n)
00938 {
00939 data_Set(data_Get().pow(n));
00940 }
00941
00942 void mcNumberHelpers::math_RaiseTo(const mcIntegerValue &n)
00943 {
00944 mcRealValue res = data_Get().pow(mcRealValue(n));
00945
00946 mcMATHLOG(wxT("mcNumberHelpers::math_RaiseTo - %s is being raised to %s; result is %s"),
00947 data_Get().GetStr().c_str(), n.GetStr().c_str(), res.GetStr().c_str());
00948
00949 data_Set(res);
00950 }
00951
00952 mcMonomial mcNumberHelpers::math_GetBaseLCM(const mcElement &p) const
00953 {
00954
00955 if (this->data_Get().isInteger() && mcNumber(p).data_Get().isInteger()) {
00956
00957 mcIntegerValue lcm = mcIntegerValue(data_Get()).LCM(mcIntegerValue(mcNumber(p).data_Get()));
00958 mcNumber res(lcm);
00959 return res;
00960 }
00961
00962 return mcExpElementHelpers::math_GetBaseLCM(p);
00963 }
00964
00965 mcMonomial mcNumberHelpers::math_GetGCD(const mcElement &p) const
00966 {
00967
00968
00969
00970 if (data_GetType() != p.data_GetType())
00971 return mcExpElementHelpers::math_GetGCD(p);
00972 if (math_CompareThisOnly(p, FALSE) &&
00973 data_Get() != 0)
00974 return mcExpElementHelpers::math_GetGCD(p);
00975
00976
00977
00978
00979
00980
00981 mcRealValue n1 = mcNumber(p).math_Evaluate();
00982 mcRealValue n2 = this->math_Evaluate();
00983
00984
00985
00986 if ((n1 == 0.0 && n2 == 0.0) ||
00987 (!n1.isInteger() || !n2.isInteger()))
00988 return *mcMonomialHelpers::smath_pOne;
00989
00990
00991 mcNumber gcd(mcIntegerValue(n1).GCD(mcIntegerValue(n2)));
00992 mcMATHLOG(wxT("mcNumberHelpers::math_GetBaseGCD - the gcd between [%s] and [%s] is [%s]"),
00993 mcTXTTHIS, mcTXT(p), mcTXT(gcd));
00994
00995
00996 mcMonomial res;
00997 res.data_AddElements(&gcd, 1);
00998 return res;
00999 }