Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4680 | right-hear | 1 | |
2 | #define __numbers_h__ |
||
3 | |||
4 | |||
5 | #include "yacasbase.h" |
||
6 | |||
7 | |||
8 | |||
9 | |||
10 | LispInt NumericSupportForMantissa(); |
||
11 | |||
12 | |||
13 | |||
14 | |||
15 | LispObject* CosFloat(LispObject* int1, LispEnvironment& aEnvironment,LispInt aPrecision); |
||
16 | LispObject* TanFloat(LispObject* int1, LispEnvironment& aEnvironment,LispInt aPrecision); |
||
17 | LispObject* ArcSinFloat(LispObject* int1, LispEnvironment& aEnvironment,LispInt aPrecision); |
||
18 | LispObject* ExpFloat(LispObject* int1, LispEnvironment& aEnvironment,LispInt aPrecision); |
||
19 | LispObject* LnFloat(LispObject* int1, LispEnvironment& aEnvironment,LispInt aPrecision); |
||
20 | |||
21 | |||
22 | LispObject* ModFloat( LispObject* int1, LispObject* int2, LispEnvironment& aEnvironment, |
||
23 | LispInt aPrecision); |
||
24 | |||
25 | |||
26 | LispEnvironment& aEnvironment,LispInt aPrecision); |
||
27 | LispObject* ShiftLeft( LispObject* int1, LispObject* int2, LispEnvironment& aEnvironment,LispInt aPrecision); |
||
28 | LispObject* ShiftRight( LispObject* int1, LispObject* int2, LispEnvironment& aEnvironment,LispInt aPrecision); |
||
29 | LispObject* LispFactorial(LispObject* int1, LispEnvironment& aEnvironment,LispInt aPrecision); |
||
30 | |||
31 | |||
32 | |||
33 | |||
34 | const unsigned GUARD_BITS = 8; // we leave this many guard bits untruncated in various situations when we need to truncate precision by hand |
||
35 | |||
36 | |||
37 | template |
||
38 | |||
39 | |||
40 | |||
41 | |||
42 | template |
||
43 | |||
44 | |||
45 | |||
46 | */ |
||
47 | |||
48 | |||
49 | |||
50 | |||
51 | |||
52 | |||
53 | |||
54 | /// All calculations are done at given precision. Integers grow as needed, floats don't grow beyond given precision. |
||
55 | class BigNumber : public YacasBase |
||
56 | { |
||
57 | public: //constructors |
||
58 | BigNumber(const LispChar * aString,LispInt aPrecision,LispInt aBase=10); |
||
59 | /// copy constructor |
||
60 | BigNumber(const BigNumber& aOther); |
||
61 | // no constructors from int or double to avoid automatic conversions |
||
62 | BigNumber(LispInt aPrecision = 20); |
||
63 | ~BigNumber(); |
||
64 | // assign from another number |
||
65 | void SetTo(const BigNumber& aOther); |
||
66 | // assign from string, precision in base digits |
||
67 | void SetTo(const LispChar * aString,LispInt aPrecision,LispInt aBase=10); |
||
68 | // assign from a platform type |
||
69 | void SetTo(long value); |
||
70 | inline void SetTo(LispInt value) { SetTo(long(value)); }; |
||
71 | void SetTo(double value); |
||
72 | public: // Convert back to other types |
||
73 | /// ToString : return string representation of number in aResult to given precision (base digits) |
||
74 | void ToString(LispString& aResult, LispInt aPrecision, LispInt aBase=10) const; |
||
75 | /// Give approximate representation as a double number |
||
76 | double Double() const; |
||
77 | |||
78 | |||
79 | LispBoolean Equals(const BigNumber& aOther) const; |
||
80 | LispBoolean IsInt() const; |
||
81 | LispBoolean IsIntValue() const; |
||
82 | LispBoolean IsSmall() const; |
||
83 | void BecomeInt(); |
||
84 | void BecomeFloat(LispInt aPrecision=0); |
||
85 | LispBoolean LessThan(const BigNumber& aOther) const; |
||
86 | public://arithmetic |
||
87 | /// Multiply two numbers at given precision and put result in *this |
||
88 | void Multiply(const BigNumber& aX, const BigNumber& aY, LispInt aPrecision); |
||
89 | /** Multiply two numbers, and add to *this (this is useful and generally efficient to implement). |
||
90 | * This is most likely going to be used by internal functions only, using aResult as an accumulator. |
||
91 | */ |
||
92 | void MultiplyAdd(const BigNumber& aX, const BigNumber& aY, LispInt aPrecision); |
||
93 | /// Add two numbers at given precision and return result in *this |
||
94 | void Add(const BigNumber& aX, const BigNumber& aY, LispInt aPrecision); |
||
95 | /// Negate the given number, return result in *this |
||
96 | void Negate(const BigNumber& aX); |
||
97 | /// Divide two numbers and return result in *this. Note: if the two arguments are integer, it should return an integer result! |
||
98 | void Divide(const BigNumber& aX, const BigNumber& aY, LispInt aPrecision); |
||
99 | |||
100 | |||
101 | void Mod(const BigNumber& aY, const BigNumber& aZ); |
||
102 | |||
103 | |||
104 | void DumpDebugInfo(); |
||
105 | |||
106 | |||
107 | /// assign self to Floor(aX) if possible |
||
108 | void Floor(const BigNumber& aX); |
||
109 | /// set precision (in bits) |
||
110 | void Precision(LispInt aPrecision); |
||
111 | |||
112 | |||
113 | void ShiftLeft( const BigNumber& aX, LispInt aNrToShift); |
||
114 | void ShiftRight( const BigNumber& aX, LispInt aNrToShift); |
||
115 | void BitAnd(const BigNumber& aX, const BigNumber& aY); |
||
116 | void BitOr(const BigNumber& aX, const BigNumber& aY); |
||
117 | void BitXor(const BigNumber& aX, const BigNumber& aY); |
||
118 | void BitNot(const BigNumber& aX); |
||
119 | /// Bit count operation: return the number of significant bits if integer, return the binary exponent if float (shortcut for binary logarithm) |
||
120 | /// give bit count as a platform integer |
||
121 | signed long BitCount() const; |
||
122 | |||
123 | |||
124 | LispInt Sign() const; |
||
125 | |||
126 | |||
127 | inline LispInt GetPrecision() const {return iPrecision;}; |
||
128 | |||
129 | |||
130 | BigNumber& operator=(const BigNumber& aOther) |
||
131 | { |
||
132 | // copy constructor not written yet, hence the assert |
||
133 | LISPASSERT(0); |
||
134 | return *this; |
||
135 | } |
||
136 | public: |
||
137 | ReferenceCount iReferenceCount; |
||
138 | private: |
||
139 | LispInt iPrecision; |
||
140 | |||
141 | |||
142 | /// Internal library wrapper starts here. |
||
143 | inline void SetIsInteger(LispBoolean aIsInteger) {iType = (aIsInteger ? KInt : KFloat);} |
||
144 | enum ENumType |
||
145 | { |
||
146 | KInt = 0, |
||
147 | KFloat |
||
148 | }; |
||
149 | ENumType iType; |
||
150 | ANumber* iNumber; |
||
151 | /// Internal library wrapper ends here. |
||
152 | }; |
||
153 | |||
154 | |||
155 | /// to convert the number of digits in some base (usually 10) to bits and back |
||
156 | |||
157 | |||
158 | // table range is from 2 to this value: |
||
159 | unsigned log2_table_range(); |
||
160 | // convert the number of digits in given base to the number of bits, and back. |
||
161 | // need to round the number of digits. |
||
162 | // These functions only work for aBase inside the allowed table range. |
||
163 | unsigned long digits_to_bits(unsigned long aDigits, unsigned aBase); |
||
164 | unsigned long bits_to_digits(unsigned long abits, unsigned aBase); |
||
165 | |||
166 | |||
167 | |||
168 |