Numworks Epsilon  1.4.1
Graphing Calculator Operating System
integer.h
Go to the documentation of this file.
1 #ifndef POINCARE_INTEGER_H
2 #define POINCARE_INTEGER_H
3 
4 #include <stdint.h>
5 #include <assert.h>
7 
8 namespace Poincare {
9 
10 /* All algorithm should be improved with:
11  * Modern Computer Arithmetic, Richard P. Brent and Paul Zimmermann */
12 
13 struct IntegerDivision;
14 
15 class Integer {
16 public:
22 
23  // FIXME: This constructor should be constexpr
25  m_digit(i>0 ? i : -i),
26  m_numberOfDigits(1),
27  m_negative(i<0)
28  {
29  }
31  Integer(const char * digits, bool negative = false); // Digits are NOT NULL-terminated
32  static Integer exponent(int fractionalPartLength, const char * exponent, int exponentLength, bool exponentNegative);
33  static Integer numerator(const char * integralPart, int integralPartLength, const char * fractionalPart, int fractionalPartLength, bool negative, Integer * exponent);
35 
36  ~Integer();
37  Integer(Integer&& other); // C++11 move constructor
38  Integer& operator=(Integer&& other); // C++11 move assignment operator
39  Integer(const Integer& other); // C++11 copy constructor
40  Integer& operator=(const Integer& other); // C++11 copy assignment operator
41 
42  // Getter & Setter
43  bool isNegative() const { return m_negative; }
44  void setNegative(bool negative);
45  int extractedInt() const { assert(m_numberOfDigits == 1 && m_digit <= k_maxExtractableInteger); return m_negative ? -m_digit : m_digit; }
46 
47  // Comparison
48  static int NaturalOrder(const Integer & i, const Integer & j);
49  bool isEqualTo(const Integer & other) const;
50  bool isLowerThan(const Integer & other) const;
51 
52  // Layout
53  int writeTextInBuffer(char * buffer, int bufferSize) const;
55 
56  // Approximation
57  template<typename T> T approximate() const;
58 
59  // Arithmetic
60  static Integer Addition(const Integer & i, const Integer & j);
61  static Integer Subtraction(const Integer & i, const Integer & j);
62  static Integer Multiplication(const Integer & i, const Integer & j);
63  static Integer Factorial(const Integer & i);
65  static Integer Power(const Integer & i, const Integer & j);
66  //static Integer Division(const Integer & i, const Integer & j);
67  //static IntegerDivision division(const Integer & i, const Integer & j);
68  bool isOne() const { return (m_numberOfDigits == 1 && digit(0) == 1 && !m_negative); };
69  bool isTwo() const { return (m_numberOfDigits == 1 && digit(0) == 2 && !m_negative); };
70  bool isTen() const { return (m_numberOfDigits == 1 && digit(0) == 10 && !m_negative); };
71  bool isMinusOne() const { return (m_numberOfDigits == 1 && digit(0) == 1 && m_negative); };
72  bool isZero() const { return (m_numberOfDigits == 1 && digit(0) == 0); };
73  constexpr static int k_maxExtractableInteger = 0x7FFFFFFF;
74 private:
75  Integer(const native_uint_t * digits, uint16_t numberOfDigits, bool negative);
76  static Integer IntegerWithHalfDigitAtIndex(half_native_uint_t halfDigit, int index);
77 
78  void releaseDynamicIvars();
79  static int8_t ucmp(const Integer & a, const Integer & b); // -1, 0, or 1
80  static Integer usum(const Integer & a, const Integer & b, bool subtract, bool outputNegative);
81  static Integer addition(const Integer & a, const Integer & b, bool inverseBNegative);
82  static IntegerDivision udiv(const Integer & a, const Integer & b);
83  bool usesImmediateDigit() const { return m_numberOfDigits == 1; }
84  native_uint_t digit(int i) const {
85  assert(i >= 0 && i < m_numberOfDigits);
86  return (usesImmediateDigit() ? m_digit : m_digits[i]);
87  }
88  uint16_t numberOfHalfDigits() const {
89  native_uint_t d = digit(m_numberOfDigits-1);
90  native_uint_t halfBase = 1 << (8*sizeof(half_native_uint_t));
91  return (d >= halfBase ? 2*m_numberOfDigits : 2*m_numberOfDigits-1);
92  }
93  half_native_uint_t halfDigit(int i) const {
94  assert(i >= 0);
95  if (i >= numberOfHalfDigits()) {
96  return 0;
97  }
98  return (usesImmediateDigit() ? ((half_native_uint_t *)&m_digit)[i] : ((half_native_uint_t *)m_digits)[i]);
99  }
100  // Small integer optimization. Similar to short string optimization.
101  union {
102  const native_uint_t * m_digits; // Little-endian
104  };
105  uint16_t m_numberOfDigits; // In base native_uint_max
106  bool m_negative; // Make sure zero cannot be negative
107 
108  static_assert(sizeof(native_int_t) <= sizeof(native_uint_t), "native_uint_t should be able to contain native_int_t data");
109  static_assert(sizeof(double_native_uint_t) == 2*sizeof(native_uint_t), "double_native_uint_t should be twice the size of native_uint_t");
110 };
111 
115 };
116 
117 }
118 
119 #endif
int32_t native_int_t
Definition: integer.h:18
T approximate() const
Definition: integer.cpp:479
uint32_t native_uint_t
Definition: integer.h:20
static Integer Power(const Integer &i, const Integer &j)
Definition: integer.cpp:313
bool isZero() const
Definition: integer.h:72
#define assert(e)
Definition: assert.h:9
int writeTextInBuffer(char *buffer, int bufferSize) const
Definition: integer.cpp:545
#define T(x)
Definition: events.cpp:26
uint64_t double_native_uint_t
Definition: integer.h:21
unsigned short uint16_t
Definition: stdint.h:5
bool isEqualTo(const Integer &other) const
Definition: integer.cpp:222
bool isTwo() const
Definition: integer.h:69
Integer & operator=(Integer &&other)
Definition: integer.cpp:164
bool isLowerThan(const Integer &other) const
Definition: integer.cpp:226
const native_uint_t * m_digits
Definition: integer.h:102
static Integer Factorial(const Integer &i)
Definition: integer.cpp:271
bool isTen() const
Definition: integer.h:70
unsigned int uint32_t
Definition: stdint.h:6
void setNegative(bool negative)
Definition: integer.cpp:203
static constexpr int k_maxExtractableInteger
Definition: integer.h:73
unsigned long long uint64_t
Definition: stdint.h:7
static Integer Addition(const Integer &i, const Integer &j)
Definition: integer.cpp:232
bool isNegative() const
Definition: integer.h:43
static Integer exponent(int fractionalPartLength, const char *exponent, int exponentLength, bool exponentNegative)
Definition: integer.cpp:86
signed char int8_t
Definition: stdint.h:9
static int NaturalOrder(const Integer &i, const Integer &j)
Definition: integer.cpp:212
bool isOne() const
Definition: integer.h:68
static Integer numerator(const char *integralPart, int integralPartLength, const char *fractionalPart, int fractionalPartLength, bool negative, Integer *exponent)
Definition: integer.cpp:100
static Integer Subtraction(const Integer &i, const Integer &j)
Definition: integer.cpp:236
uint16_t half_native_uint_t
Definition: integer.h:17
Integer(native_int_t i=0)
Definition: integer.h:24
ExpressionLayout * createLayout() const
Definition: integer.cpp:590
bool isMinusOne() const
Definition: integer.h:71
signed long long int64_t
Definition: stdint.h:12
signed int int32_t
Definition: stdint.h:11
static Integer Multiplication(const Integer &i, const Integer &j)
Definition: integer.cpp:240
static Integer denominator(Integer *exponent)
Definition: integer.cpp:117
static IntegerDivision Division(const Integer &numerator, const Integer &denominator)
Definition: integer.cpp:281
native_uint_t m_digit
Definition: integer.h:103
int64_t double_native_int_t
Definition: integer.h:19
int extractedInt() const
Definition: integer.h:45