Subversion Repositories Kolibri OS

Rev

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 inline T MIN(T x, T y) { if (x>y) return y; else return x; }
38
39
 
40
41
 
42
template inline T DIST(T x, T y) { return (x>=y+DIST_BITS || y>=x+DIST_BITS) ? 0 : 1; }
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