Number.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /******************************************************************************
  2. Use 'Number' for handling numbers with very big precision.
  3. /******************************************************************************/
  4. #define NUMBER_DIGS 32 // number of 'Number' digits
  5. /******************************************************************************/
  6. struct Number // Number with big precision (NUMBER_DIGS*16 bit precision)
  7. {
  8. Bool sign ; // sign (false=positive, true=negative)
  9. UShort d[NUMBER_DIGS]; // digits
  10. // get / set
  11. #if EE_PRIVATE
  12. Int digits()C; // get number of used digits (this is the highest non zero digit index +1)
  13. #endif
  14. Number& zero(); // set to zero
  15. Int asInt ()C; // return as Int
  16. UInt asUInt ()C; // return as UInt
  17. Long asLong ()C; // return as Long
  18. ULong asULong()C; // return as ULong
  19. Flt asFlt ()C; // return as Flt
  20. Dbl asDbl ()C; // return as Dbl
  21. UShort dig (UInt i)C {return InRange(i, d) ? d[i] : 0;} // safe get digit, 0 if 'i' is invalid
  22. UShort digMod(UInt i)C {return d[i&(NUMBER_DIGS-1)] ;} // safe get digit, d[i%NUMBER_DIGS]
  23. // Int / Real
  24. Bool isReal()C {return _real;} // if the number is of Real type
  25. Bool isInt ()C {return !_real;} // if the number is of Int type
  26. Number& toReal(); // convert to Real
  27. Number& toInt (); // convert to Int
  28. // compare
  29. friend Int Compare (C Number &n0, C Number &n1); // compare
  30. friend Int Compare (C Number &n0, C Int &n1); // compare
  31. friend Bool operator==(C Number &n0, C Number &n1) {return Compare(n0, n1)==0;} // if equal
  32. friend Bool operator==(C Number &n0, Int n1) {return Compare(n0, n1)==0;} // if equal
  33. friend Bool operator!=(C Number &n0, C Number &n1) {return Compare(n0, n1)!=0;} // if not equal
  34. friend Bool operator!=(C Number &n0, Int n1) {return Compare(n0, n1)!=0;} // if not equal
  35. friend Bool operator>=(C Number &n0, C Number &n1) {return Compare(n0, n1)>=0;} // if greater or equal
  36. friend Bool operator>=(C Number &n0, Int n1) {return Compare(n0, n1)>=0;} // if greater or equal
  37. friend Bool operator<=(C Number &n0, C Number &n1) {return Compare(n0, n1)<=0;} // if smaller or equal
  38. friend Bool operator<=(C Number &n0, Int n1) {return Compare(n0, n1)<=0;} // if smaller or equal
  39. friend Bool operator> (C Number &n0, C Number &n1) {return Compare(n0, n1)> 0;} // if greater
  40. friend Bool operator> (C Number &n0, Int n1) {return Compare(n0, n1)> 0;} // if greater
  41. friend Bool operator< (C Number &n0, C Number &n1) {return Compare(n0, n1)< 0;} // if smaller
  42. friend Bool operator< (C Number &n0, Int n1) {return Compare(n0, n1)< 0;} // if smaller
  43. // add / subtract / multiply / divide / mod
  44. Number& operator+=(C Number &N); Number& operator+=(Int); Number& operator+=(Dbl); Number& operator++() {T+=1; return T;} void operator++(Int) {T+=1;} // add
  45. Number& operator-=(C Number &N); Number& operator-=(Int); Number& operator-=(Dbl); Number& operator--() {T-=1; return T;} void operator--(Int) {T-=1;} // subtract
  46. Number& operator*=(C Number &N); Number& operator*=(Int); Number& operator*=(Dbl); // multiply
  47. Number& operator/=(C Number &N); Number& operator/=(Int); Number& operator/=(Dbl); // divide
  48. Number& operator%=(C Number &N); Number& operator%=(Int); // mod
  49. friend Number operator+ (C Number &a, C Number &b); friend Number operator+(C Number&, Int); friend Number operator+(Int, C Number&); friend Number operator+(C Number&, Dbl); friend Number operator+(Dbl, C Number&); // add
  50. friend Number operator- (C Number &a, C Number &b); friend Number operator-(C Number&, Int); friend Number operator-(Int, C Number&); friend Number operator-(C Number&, Dbl); friend Number operator-(Dbl, C Number&); // subtract
  51. friend Number operator* (C Number &a, C Number &b); friend Number operator*(C Number&, Int); friend Number operator*(Int, C Number&); friend Number operator*(C Number&, Dbl); friend Number operator*(Dbl, C Number&); // multiply
  52. friend Number operator/ (C Number &a, C Number &b); friend Number operator/(C Number&, Int); friend Number operator/(Int, C Number&); friend Number operator/(C Number&, Dbl); friend Number operator/(Dbl, C Number&); // divide
  53. friend Number operator% (C Number &a, C Number &b); // mod
  54. // sqr / sqrt
  55. Number& sqr (); // T*=T (square)
  56. Number& sqrt(); // T =sqrt(T) (square-root)
  57. // shift / rotate
  58. Number& operator<<=( Int bits); // shift bits left
  59. Number& operator>>=( Int bits); // shift bits right
  60. friend Number operator<< (C Number &a, Int bits); // shift bits left
  61. friend Number operator>> (C Number &a, Int bits); // shift bits right
  62. Number& rol( Int bits); // rotate bits left
  63. Number& ror( Int bits); // rotate bits right
  64. #if EE_PRIVATE
  65. Number& setShlDig(C Number &N, Int digs); // shift digits left "T =N<<(d*16)"
  66. Number& setShrDig(C Number &N, Int digs); // shift digits right "T =N>>(d*16)"
  67. Number& shlDig( Int digs); // shift digits left "T<<= (d*16)"
  68. Number& shrDig( Int digs); // shift digits right "T>>= (d*16)"
  69. #endif
  70. Number() {}
  71. Number& operator=( Int i); Number(Int i) {T=i;}
  72. Number& operator=( UInt u); Number(UInt u) {T=u;}
  73. Number& operator=( Long i); Number(Long i) {T=i;}
  74. Number& operator=( ULong u); Number(ULong u) {T=u;}
  75. Number& operator=( Flt f); Number(Flt f) {T=f;}
  76. Number& operator=( Dbl f); Number(Dbl f) {T=f;}
  77. Number& operator=(C Str &s); // set from string
  78. #if EE_PRIVATE
  79. Int rawCompare(C Number &N)C;
  80. Int rawCompare( UInt N)C;
  81. Int absCompare(C Number &N)C;
  82. Int absCompare( UInt N)C;
  83. Int absCompare( Int N)C {return absCompare((UInt)Abs(N));}
  84. Number& rawAdd(C Number &N);
  85. Number& rawSub(C Number &N);
  86. Number& absAdd(C Number &N);
  87. Number& absAdd( UInt N);
  88. Number& absSub(C Number &N);
  89. Number& absSub( UInt N);
  90. #endif
  91. #if !EE_PRIVATE
  92. private:
  93. #endif
  94. Bool _real;
  95. };
  96. /******************************************************************************/
  97. struct Number2
  98. {
  99. Number x, y;
  100. Number2& zero( ) {x.zero(); y.zero(); return T;}
  101. Number2& set ( Dbl r ) {x=y=r; return T;}
  102. Number2& set ( Dbl x, Dbl y) {T.x=x; T.y=y; return T;}
  103. Number2& set (C Number &x, C Number &y) {T.x=x; T.y=y; return T;}
  104. Number2& operator+=(Dbl r) {x+= r; y+= r; return T;}
  105. Number2& operator-=(Dbl r) {x-= r; y-= r; return T;}
  106. Number2& operator*=(Dbl r) {x*= r; y*= r; return T;}
  107. Number2& operator/=(Dbl r) {x/= r; y/= r; return T;}
  108. Number2& operator+=(Number &n) {x+=n ; y+=n ; return T;}
  109. Number2& operator-=(Number &n) {x-=n ; y-=n ; return T;}
  110. Number2& operator*=(Number &n) {x*=n ; y*=n ; return T;}
  111. Number2& operator/=(Number &n) {x/=n ; y/=n ; return T;}
  112. Number2& operator+=(Number2 &n) {x+=n.x; y+=n.y; return T;}
  113. Number2& operator-=(Number2 &n) {x-=n.x; y-=n.y; return T;}
  114. Number2& operator*=(Number2 &n) {x*=n.x; y*=n.y; return T;}
  115. Number2& operator/=(Number2 &n) {x/=n.x; y/=n.y; return T;}
  116. friend Number2 operator+ (C Number2 &n, Dbl r) {return Number2(n.x+r, n.y+r);}
  117. friend Number2 operator- (C Number2 &n, Dbl r) {return Number2(n.x-r, n.y-r);}
  118. friend Number2 operator* (C Number2 &n, Dbl r) {return Number2(n.x*r, n.y*r);}
  119. friend Number2 operator/ (C Number2 &n, Dbl r) {return Number2(n.x/r, n.y/r);}
  120. friend Number2 operator+ ( Dbl r, C Number2 &n) {return Number2(r+n.x, r+n.y);}
  121. friend Number2 operator- ( Dbl r, C Number2 &n) {return Number2(r-n.x, r-n.y);}
  122. friend Number2 operator* ( Dbl r, C Number2 &n) {return Number2(r*n.x, r*n.y);}
  123. friend Number2 operator/ ( Dbl r, C Number2 &n) {return Number2(r/n.x, r/n.y);}
  124. friend Number2 operator+ (C Number2 &n, C Number &r) {return Number2(n.x+r, n.y+r);}
  125. friend Number2 operator- (C Number2 &n, C Number &r) {return Number2(n.x-r, n.y-r);}
  126. friend Number2 operator* (C Number2 &n, C Number &r) {return Number2(n.x*r, n.y*r);}
  127. friend Number2 operator/ (C Number2 &n, C Number &r) {return Number2(n.x/r, n.y/r);}
  128. friend Number2 operator+ (C Number &r, C Number2 &n) {return Number2(r+n.x, r+n.y);}
  129. friend Number2 operator- (C Number &r, C Number2 &n) {return Number2(r-n.x, r-n.y);}
  130. friend Number2 operator* (C Number &r, C Number2 &n) {return Number2(r*n.x, r*n.y);}
  131. friend Number2 operator/ (C Number &r, C Number2 &n) {return Number2(r/n.x, r/n.y);}
  132. friend Number2 operator+ (C Number2 &a, C Number2 &b) {return Number2(a.x+b.x, a.y+b.y);}
  133. friend Number2 operator- (C Number2 &a, C Number2 &b) {return Number2(a.x-b.x, a.y-b.y);}
  134. friend Number2 operator* (C Number2 &a, C Number2 &b) {return Number2(a.x*b.x, a.y*b.y);}
  135. friend Number2 operator/ (C Number2 &a, C Number2 &b) {return Number2(a.x/b.x, a.y/b.y);}
  136. Number length ()C; // get length
  137. Number length2 ()C; // get squared length
  138. Number normalize() ; // normalize length and return previous length
  139. Number2() {}
  140. Number2( Dbl r ) {set(r );}
  141. Number2( Dbl x, Dbl y) {set(x, y);}
  142. Number2(C Number &x, C Number &y) {set(x, y);}
  143. };
  144. /******************************************************************************/
  145. struct Number3
  146. {
  147. Number x, y, z;
  148. Number2& n2() {return (Number2&)T;} // get this as Number2 format (using x, y members only), this returns reference to self and not a new object!
  149. C Number2& n2()C {return (Number2&)T;} // get this as const Number2 format (using x, y members only), this returns reference to self and not a new object!
  150. Number3& zero( ) {x.zero(); y.zero(); z.zero(); return T;}
  151. Number3& set ( Dbl r ) {x=y=z=r; return T;}
  152. Number3& set ( Dbl x, Dbl y, Dbl z) {T.x=x; T.y=y; T.z=z; return T;}
  153. Number3& set (C Number &x, C Number &y, C Number &z) {T.x=x; T.y=y; T.z=z; return T;}
  154. Number3& set (C Number2 &n2 , C Number &z) {T.n2()=n2; T.z=z; return T;}
  155. Number3& operator+=( Dbl r) {x+= r; y+= r; z+= r; return T;}
  156. Number3& operator-=( Dbl r) {x-= r; y-= r; z-= r; return T;}
  157. Number3& operator*=( Dbl r) {x*= r; y*= r; z*= r; return T;}
  158. Number3& operator/=( Dbl r) {x/= r; y/= r; z/= r; return T;}
  159. Number3& operator+=(C Number &n) {x+=n ; y+=n ; z+=n ; return T;}
  160. Number3& operator-=(C Number &n) {x-=n ; y-=n ; z-=n ; return T;}
  161. Number3& operator*=(C Number &n) {x*=n ; y*=n ; z*=n ; return T;}
  162. Number3& operator/=(C Number &n) {x/=n ; y/=n ; z/=n ; return T;}
  163. Number3& operator+=(C Number3 &n) {x+=n.x; y+=n.y; z+=n.z; return T;}
  164. Number3& operator-=(C Number3 &n) {x-=n.x; y-=n.y; z-=n.z; return T;}
  165. Number3& operator*=(C Number3 &n) {x*=n.x; y*=n.y; z*=n.z; return T;}
  166. Number3& operator/=(C Number3 &n) {x/=n.x; y/=n.y; z/=n.z; return T;}
  167. friend Number3 operator+ (C Number3 &n, Dbl r) {return Number3(n.x+r, n.y+r, n.z+r);}
  168. friend Number3 operator- (C Number3 &n, Dbl r) {return Number3(n.x-r, n.y-r, n.z-r);}
  169. friend Number3 operator* (C Number3 &n, Dbl r) {return Number3(n.x*r, n.y*r, n.z*r);}
  170. friend Number3 operator/ (C Number3 &n, Dbl r) {return Number3(n.x/r, n.y/r, n.z/r);}
  171. friend Number3 operator+ ( Dbl r, C Number3 &n) {return Number3(r+n.x, r+n.y, r+n.z);}
  172. friend Number3 operator- ( Dbl r, C Number3 &n) {return Number3(r-n.x, r-n.y, r-n.z);}
  173. friend Number3 operator* ( Dbl r, C Number3 &n) {return Number3(r*n.x, r*n.y, r*n.z);}
  174. friend Number3 operator/ ( Dbl r, C Number3 &n) {return Number3(r/n.x, r/n.y, r/n.z);}
  175. friend Number3 operator+ (C Number3 &n, C Number &r) {return Number3(n.x+r, n.y+r, n.z+r);}
  176. friend Number3 operator- (C Number3 &n, C Number &r) {return Number3(n.x-r, n.y-r, n.z-r);}
  177. friend Number3 operator* (C Number3 &n, C Number &r) {return Number3(n.x*r, n.y*r, n.z*r);}
  178. friend Number3 operator/ (C Number3 &n, C Number &r) {return Number3(n.x/r, n.y/r, n.z/r);}
  179. friend Number3 operator+ (C Number &r, C Number3 &n) {return Number3(r+n.x, r+n.y, r+n.z);}
  180. friend Number3 operator- (C Number &r, C Number3 &n) {return Number3(r-n.x, r-n.y, r-n.z);}
  181. friend Number3 operator* (C Number &r, C Number3 &n) {return Number3(r*n.x, r*n.y, r*n.z);}
  182. friend Number3 operator/ (C Number &r, C Number3 &n) {return Number3(r/n.x, r/n.y, r/n.z);}
  183. friend Number3 operator+ (C Number3 &a, C Number3 &b) {return Number3(a.x+b.x, a.y+b.y, a.z+b.z);}
  184. friend Number3 operator- (C Number3 &a, C Number3 &b) {return Number3(a.x-b.x, a.y-b.y, a.z-b.z);}
  185. friend Number3 operator* (C Number3 &a, C Number3 &b) {return Number3(a.x*b.x, a.y*b.y, a.z*b.z);}
  186. friend Number3 operator/ (C Number3 &a, C Number3 &b) {return Number3(a.x/b.x, a.y/b.y, a.z/b.z);}
  187. Number length ()C; // get length
  188. Number length2 ()C; // get squared length
  189. Number normalize() ; // normalize length and return previous length
  190. Number3() {}
  191. Number3( Dbl r ) {set(r );}
  192. Number3( Dbl x , Dbl y, Dbl z) {set(x, y, z);}
  193. Number3(C Number &x , C Number &y, C Number &z) {set(x, y, z);}
  194. Number3(C Number2 &n2, C Number &z) {set(n2 , z);}
  195. };
  196. /******************************************************************************/
  197. inline Number Dot(C Number2 &a, C Number2 &b) {return a.x*b.x + a.y*b.y ;}
  198. inline Number Dot(C Number3 &a, C Number3 &b) {return a.x*b.x + a.y*b.y + a.z*b.z;}
  199. /******************************************************************************/