Number.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. namespace EE{
  4. /******************************************************************************
  5. TODO: in the future use SByte exp/shift as Number member to have more control of the value range.
  6. sin(x) = x - x**3/ 3!
  7. cos(x) = 1 - x**2/ 2! + x**4/ 4! - x**6/ 6! ..
  8. tan(x) = x + x**3/ 3!
  9. /******************************************************************************/
  10. #if NUMBER_DIGS<4
  11. #error NUMBER_DIGS must be >= 4
  12. #elif !IS_POW_2(NUMBER_DIGS)
  13. #error NUMBER_DIGS must be a power of 2
  14. #endif
  15. #pragma runtime_checks("", off)
  16. /******************************************************************************/
  17. Int Number::digits()C
  18. {
  19. REP(NUMBER_DIGS)if(d[i])return i+1;
  20. return 0;
  21. }
  22. Number& Number::zero()
  23. {
  24. Zero(T);
  25. return T;
  26. }
  27. Int Number::asInt ()C {UInt u=(U32&)d[_real ? NUMBER_DIGS/2 : 0]; return sign ? -Int (u) : u;}
  28. UInt Number::asUInt ()C {return (U32&)d[_real ? NUMBER_DIGS/2 : 0];}
  29. Long Number::asLong ()C {ULong u=(U64&)d[_real ? NUMBER_DIGS/2 : 0]; return sign ? -Long(u) : u;}
  30. ULong Number::asULong()C {return (U64&)d[_real ? NUMBER_DIGS/2 : 0];}
  31. // !! keep as operator=, even though these could be converted to constructors, Android toolchain will throw compilation errors !!
  32. Number& Number::operator=(Int i) {zero(); sign=(i<0); *(U32*)d=Abs(i); return T;}
  33. Number& Number::operator=(UInt u) {zero(); *(U32*)d= u ; return T;}
  34. Number& Number::operator=(Long i) {zero(); sign=(i<0); *(U64*)d=Abs(i); return T;}
  35. Number& Number::operator=(ULong u) {zero(); *(U64*)d= u ; return T;}
  36. Flt Number::asFlt()C
  37. {
  38. if(!_real)return asInt();
  39. if(Int digits=T.digits())
  40. {
  41. digits--;
  42. UInt pos=digits*16+BitHi(Unsigned(d[digits]));
  43. Int exp=Mid(pos+(_real ? -NUMBER_DIGS*16/2 : 0), -127, 127);
  44. UInt significand=0;
  45. pos-- ; if(pos<NUMBER_DIGS*16)significand|=Shr(d[pos>>4], (pos&15)-22);
  46. pos-=16; if(pos<NUMBER_DIGS*16)significand|=Shr(d[pos>>4], (pos&15)- 6);
  47. pos-=16; if(pos<NUMBER_DIGS*16)significand|=Shr(d[pos>>4], (pos&15)+10);
  48. UInt f=(sign<<31)|(((exp+127)&0xFF)<<23)|(significand&0x7FFFFF);
  49. return (Flt&)f;
  50. }
  51. return 0;
  52. }
  53. Dbl Number::asDbl()C
  54. {
  55. if(!_real)return asLong();
  56. if(Int digits=T.digits())
  57. {
  58. digits--;
  59. UInt pos=digits*16+BitHi(Unsigned(d[digits]));
  60. Int exp=Mid(pos+(_real ? -NUMBER_DIGS*16/2 : 0), -1023, 1023);
  61. U32 m0=0, m1=0;
  62. pos-- ; if(pos<NUMBER_DIGS*16) m0|=Shr(d[pos>>4], (pos&15)-19);
  63. pos-=16; if(pos<NUMBER_DIGS*16){m0|=Shr(d[pos>>4], (pos&15)- 3); m1|=Shr(d[pos>>4], (pos&15)-35);}
  64. pos-=16; if(pos<NUMBER_DIGS*16){m0|=Shr(d[pos>>4], (pos&15)+13); m1|=Shr(d[pos>>4], (pos&15)-19);}
  65. pos-=16; if(pos<NUMBER_DIGS*16) m1|=Shr(d[pos>>4], (pos&15)- 3);
  66. pos-=16; if(pos<NUMBER_DIGS*16) m1|=Shr(d[pos>>4], (pos&15)+13);
  67. U32 f[2]=
  68. {
  69. m1,
  70. (m0&0xFFFFF)|(((exp+1023)&0x7FF)<<20)|(sign<<31),
  71. };
  72. return (Dbl&)f[0];
  73. }
  74. return 0;
  75. }
  76. Number& Number::operator=(Flt f)
  77. {
  78. zero();
  79. U32 d =(U32&)f,
  80. significand=(d&0x7FFFFF);
  81. Int exp =((d>>23)&0xFF)-127;
  82. sign =((d>>31)!=0);
  83. UInt pos =exp+NUMBER_DIGS*16/2;
  84. _real =true;
  85. if(pos<NUMBER_DIGS*16)T.d[pos>>4] = (1<<(pos&15) );
  86. pos-- ; if(pos<NUMBER_DIGS*16)T.d[pos>>4]|=Shl(significand, (pos&15)-22);
  87. pos-=16; if(pos<NUMBER_DIGS*16)T.d[pos>>4]|=Shl(significand, (pos&15)- 6);
  88. pos-=16; if(pos<NUMBER_DIGS*16)T.d[pos>>4]|=Shl(significand, (pos&15)+10);
  89. return T;
  90. }
  91. Number& Number::operator=(Dbl f)
  92. {
  93. zero();
  94. U32 *d =(U32*)&f,
  95. m0 =(d[1]&0xFFFFF),
  96. m1 =(d[0]);
  97. Int exp =((d[1]>>20)&0x7FF)-1023;
  98. sign=((d[1]>>31)!=0);
  99. UInt pos =exp+NUMBER_DIGS*16/2;
  100. _real=true;
  101. if(pos<NUMBER_DIGS*16)T.d[pos>>4] = (1<<(pos&15) );
  102. pos-- ; if(pos<NUMBER_DIGS*16)T.d[pos>>4]|=Shl(m0, (pos&15)-19);
  103. pos-=16; if(pos<NUMBER_DIGS*16)T.d[pos>>4]|=Shl(m0, (pos&15)- 3)|Shl(m1, (pos&15)-35);
  104. pos-=16; if(pos<NUMBER_DIGS*16)T.d[pos>>4]|=Shl(m0, (pos&15)+13)|Shl(m1, (pos&15)-19);
  105. pos-=16; if(pos<NUMBER_DIGS*16)T.d[pos>>4]|= Shl(m1, (pos&15)- 3);
  106. pos-=16; if(pos<NUMBER_DIGS*16)T.d[pos>>4]|= Shl(m1, (pos&15)+13);
  107. return T;
  108. }
  109. Number& Number::operator=(C Str &s)
  110. {
  111. Int mode=10;
  112. Number frac_m=1.0f;
  113. zero();
  114. if(CChar *t=s)
  115. {
  116. if(t[0]=='-'){sign=true; t++;}
  117. if(t[0]=='0')
  118. {
  119. if(t[1]=='b' || t[1]=='B'){t+=2; mode= 2;}else
  120. if(t[1]=='x' || t[1]=='X'){t+=2; mode=16;}
  121. }
  122. for(;;)
  123. {
  124. Char c=*t++;
  125. if(c=='.')
  126. {
  127. if(!_real)toReal();
  128. }else
  129. {
  130. Int i=CharInt(c);
  131. if(!InRange(i, mode))break;
  132. if(!_real){T*=mode; T+=i;}
  133. else T+=(frac_m/=mode)*i;
  134. }
  135. }
  136. }
  137. return T;
  138. }
  139. /******************************************************************************/
  140. Number& Number::toReal() {if(!_real){shlDig(NUMBER_DIGS/2); _real=true ;} return T;}
  141. Number& Number::toInt () {if( _real){shrDig(NUMBER_DIGS/2); _real=false;} return T;}
  142. /******************************************************************************/
  143. Int Number::rawCompare(C Number &N)C
  144. {
  145. REP(NUMBER_DIGS)
  146. {
  147. Int d=T.d[i]-N.d[i];
  148. if(d>0)return +1;
  149. if(d<0)return -1;
  150. }
  151. return 0;
  152. }
  153. Int Number::rawCompare(UInt N)C
  154. {
  155. for(Int i=NUMBER_DIGS-1; i>=2; i--)if(d[i])return +1;
  156. Int d=T.d[1]-(N>>16 ); if(d>0)return +1; if(d<0)return -1;
  157. d=T.d[0]-(N&0xFFFF); if(d>0)return +1; if(d<0)return -1;
  158. return 0;
  159. }
  160. Int Number::absCompare(C Number &N)C
  161. {
  162. if(_real==N._real)
  163. {
  164. return rawCompare(N);
  165. }else
  166. {
  167. if(_real){REP(NUMBER_DIGS/2)if(N.d[i+NUMBER_DIGS/2])return -1; REP(NUMBER_DIGS/2){Int d=T.d[i+NUMBER_DIGS/2]-N.d[i]; if(d>0)return +1; if(d<0)return -1;} REP(NUMBER_DIGS/2)if(T.d[i])return +1;}
  168. else {REP(NUMBER_DIGS/2)if(T.d[i+NUMBER_DIGS/2])return +1; REP(NUMBER_DIGS/2){Int d=T.d[i]-N.d[i+NUMBER_DIGS/2]; if(d>0)return +1; if(d<0)return -1;} REP(NUMBER_DIGS/2)if(N.d[i])return -1;}
  169. }
  170. return 0;
  171. }
  172. Int Number::absCompare(UInt N)C
  173. {
  174. if(!_real)
  175. {
  176. return rawCompare(N);
  177. }else
  178. {
  179. for(Int i=NUMBER_DIGS-1; i>=NUMBER_DIGS/2+2; i--)if(d[i])return +1;
  180. Int d=T.d[NUMBER_DIGS/2+1]-(N>>16 ); if(d>0)return +1; if(d<0)return -1;
  181. d=T.d[NUMBER_DIGS/2 ]-(N&0xFFFF); if(d>0)return +1; if(d<0)return -1;
  182. REP(NUMBER_DIGS/2)if(T.d[i])return +1;
  183. }
  184. return 0;
  185. }
  186. Int Compare(C Number &n0, C Number &n1) {if(n0.sign== n1.sign)return n0.sign ? -n0.absCompare( n1 ) : n0.absCompare( n1 ); return n0.sign ? -1 : +1;}
  187. Int Compare(C Number &n0, C Int &n1) {if(n0.sign==(n1<0 ))return n0.sign ? -n0.absCompare(Abs(n1)) : n0.absCompare(Abs(n1)); return n0.sign ? -1 : +1;}
  188. /******************************************************************************/
  189. // SHIFT ROLL
  190. /******************************************************************************/
  191. Number& Number::operator<<=(Int bits)
  192. {
  193. if(bits>0)
  194. {
  195. UInt D=bits>>4; bits&=15;
  196. UInt r=16-bits;
  197. REP(NUMBER_DIGS)
  198. {
  199. UInt j=i-D;
  200. T.d[i]=(dig(j )<<bits)
  201. |(dig(j-1)>>r );
  202. }
  203. }else if(bits)T>>=(-bits);
  204. return T;
  205. }
  206. Number& Number::operator>>=(Int bits)
  207. {
  208. if(bits>0)
  209. {
  210. UInt D=bits>>4; bits&=15;
  211. UInt r=16-bits;
  212. FREP(NUMBER_DIGS)
  213. {
  214. UInt j=i+D;
  215. T.d[i]=(dig(j )>>bits)
  216. |(dig(j+1)<<r );
  217. }
  218. }else if(bits)T<<=(-bits);
  219. return T;
  220. }
  221. Number& Number::rol(Int bits)
  222. {
  223. if(bits>0)
  224. {
  225. UInt D=bits>>4; bits&=15;
  226. UInt r=16-bits;
  227. REP(NUMBER_DIGS)
  228. {
  229. UInt j=i-D;
  230. T.d[i]=(digMod(j )<<bits)
  231. |(digMod(j-1)>>r );
  232. }
  233. }else if(bits)ror(-bits);
  234. return T;
  235. }
  236. Number& Number::ror(Int bits)
  237. {
  238. if(bits>0)
  239. {
  240. UInt D=bits>>4; bits&=15;
  241. UInt r=16-bits;
  242. FREP(NUMBER_DIGS)
  243. {
  244. UInt j=i+D;
  245. T.d[i]=(digMod(j )>>bits)
  246. |(digMod(j+1)<<r );
  247. }
  248. }else if(bits)rol(-bits);
  249. return T;
  250. }
  251. Number& Number::setShlDig(C Number &N, Int digs)
  252. {
  253. if(digs>0){sign=N.sign; _real=N._real; REP(NUMBER_DIGS)T.d[i]=N.dig(i-digs);}else
  254. if(digs<0)setShrDig(N, -digs);else T=N;
  255. return T;
  256. }
  257. Number& Number::setShrDig(C Number &N, Int digs)
  258. {
  259. if(digs>0){sign=N.sign; _real=N._real; FREP(NUMBER_DIGS)T.d[i]=N.dig(i+digs);}else
  260. if(digs<0)setShlDig(N, -digs);else T=N;
  261. return T;
  262. }
  263. Number& Number::shlDig(Int digs)
  264. {
  265. if(digs>0)REP(NUMBER_DIGS)T.d[i]=dig(i-digs);else
  266. if(digs<0)shrDig(-digs);
  267. return T;
  268. }
  269. Number& Number::shrDig(Int digs)
  270. {
  271. if(digs>0)FREP(NUMBER_DIGS)T.d[i]=dig(i+digs);else
  272. if(digs<0)shlDig(-digs);
  273. return T;
  274. }
  275. Number operator<<(C Number &a, Int bits) {return Number(a)<<=bits;}
  276. Number operator>>(C Number &a, Int bits) {return Number(a)>>=bits;}
  277. /******************************************************************************/
  278. // ADD SUB MUL DIV MOD
  279. /******************************************************************************/
  280. Number& Number::rawAdd(C Number &N)
  281. {
  282. UInt x=0;
  283. FREP(NUMBER_DIGS)
  284. {
  285. x +=d[i]+N.d[i];
  286. d[i]=x;
  287. x >>=16;
  288. }
  289. return T;
  290. }
  291. Number& Number::rawSub(C Number &N)
  292. {
  293. Byte carry=0;
  294. if(rawCompare(N)>=0)
  295. {
  296. FREP(NUMBER_DIGS)
  297. {
  298. Int x=d[i]-N.d[i]-carry;
  299. d[i] =x;
  300. carry=(x<0);
  301. }
  302. }else
  303. {
  304. FREP(NUMBER_DIGS)
  305. {
  306. Int x=N.d[i]-d[i]-carry;
  307. d[i] =x;
  308. carry=(x<0);
  309. }
  310. sign^=1;
  311. }
  312. return T;
  313. }
  314. Number& Number::absAdd(C Number &N)
  315. {
  316. if(!_real && N._real)toReal();
  317. if( _real == N._real)
  318. {
  319. rawAdd(N);
  320. }else
  321. {
  322. UInt x=0;
  323. for(Int i=NUMBER_DIGS/2; i<NUMBER_DIGS; i++)
  324. {
  325. x +=d[i]+N.d[i-NUMBER_DIGS/2];
  326. d[i]=x;
  327. x >>=16;
  328. }
  329. }
  330. return T;
  331. }
  332. Number& Number::absAdd(UInt N)
  333. {
  334. UInt x=0;
  335. if(!_real)
  336. {
  337. FREP(NUMBER_DIGS)
  338. {
  339. x+=d[i]+(N&0xFFFF);
  340. d[i]=x;
  341. x >>=16;
  342. N >>=16;
  343. }
  344. }else
  345. {
  346. for(Int i=NUMBER_DIGS/2; i<NUMBER_DIGS; i++)
  347. {
  348. x+=d[i]+(N&0xFFFF);
  349. d[i]=x;
  350. x >>=16;
  351. N >>=16;
  352. }
  353. }
  354. return T;
  355. }
  356. Number& Number::absSub(C Number &N)
  357. {
  358. if(!_real && N._real)toReal();
  359. if( _real == N._real)
  360. {
  361. rawSub(N);
  362. }else
  363. {
  364. Byte carry=0;
  365. if(absCompare(N)>=0)
  366. {
  367. for(Int i=NUMBER_DIGS/2; i<NUMBER_DIGS; i++)
  368. {
  369. Int x=d[i]-N.d[i-NUMBER_DIGS/2]-carry;
  370. d[i] =x;
  371. carry=(x<0);
  372. }
  373. }else
  374. {
  375. FREP(NUMBER_DIGS/2)
  376. {
  377. Int x=-d[i]-carry;
  378. d[i] =x;
  379. carry=(x<0);
  380. }
  381. for(Int i=NUMBER_DIGS/2; i<NUMBER_DIGS; i++)
  382. {
  383. Int x=N.d[i-NUMBER_DIGS/2]-d[i]-carry;
  384. d[i] =x;
  385. carry=(x<0);
  386. }
  387. sign^=1;
  388. }
  389. }
  390. return T;
  391. }
  392. Number& Number::absSub(UInt N)
  393. {
  394. Byte carry=0;
  395. if(!_real)
  396. {
  397. if(rawCompare(N)>=0)
  398. {
  399. FREP(NUMBER_DIGS)
  400. {
  401. Int x=d[i]-(N&0xFFFF)-carry;
  402. d[i] =x;
  403. carry=(x<0);
  404. N >>=16;
  405. }
  406. }else
  407. {
  408. FREP(NUMBER_DIGS)
  409. {
  410. Int x=(N&0xFFFF)-d[i]-carry;
  411. d[i] =x;
  412. carry=(x<0);
  413. N >>=16;
  414. }
  415. sign^=1;
  416. }
  417. }else
  418. {
  419. if(absCompare(N)>=0)
  420. {
  421. for(Int i=NUMBER_DIGS/2; i<NUMBER_DIGS; i++)
  422. {
  423. Int x=d[i]-(N&0xFFFF)-carry;
  424. d[i] =x;
  425. carry=(x<0);
  426. N >>=16;
  427. }
  428. }else
  429. {
  430. FREP(NUMBER_DIGS/2)
  431. {
  432. Int x=-d[i]-carry;
  433. d[i] =x;
  434. carry=(x<0);
  435. }
  436. for(Int i=NUMBER_DIGS/2; i<NUMBER_DIGS; i++)
  437. {
  438. Int x=(N&0xFFFF)-d[i]-carry;
  439. d[i] =x;
  440. carry=(x<0);
  441. N >>=16;
  442. }
  443. sign^=1;
  444. }
  445. }
  446. return T;
  447. }
  448. /******************************************************************************/
  449. Number& Number::operator+=(C Number &N) {if(sign==N.sign)absAdd( N );else absSub( N ); return T;}
  450. Number& Number::operator+=( Int N) {if(sign==(N<0 ))absAdd(Abs(N));else absSub(Abs(N)); return T;}
  451. Number& Number::operator-=(C Number &N) {if(sign==N.sign)absSub( N );else absAdd( N ); return T;}
  452. Number& Number::operator-=( Int N) {if(sign==(N<0 ))absSub(Abs(N));else absAdd(Abs(N)); return T;}
  453. /******************************************************************************/
  454. Number& Number::operator*=(C Number &N)
  455. {
  456. Number t0, t1;
  457. t0.zero().sign=sign^N.sign;
  458. FREPD(n0, NUMBER_DIGS)
  459. {
  460. t1.zero();
  461. UInt x=0;
  462. if(!_real || !N._real)
  463. {
  464. FREPD(n1, NUMBER_DIGS)
  465. {
  466. if(n0+n1>=NUMBER_DIGS)break;
  467. x+=d[n0]*N.d[n1];
  468. t1.d[n0+n1]=x;
  469. x>>=16;
  470. }
  471. }else
  472. {
  473. FREPD(n1, NUMBER_DIGS)
  474. {
  475. x+=d[n0]*N.d[n1];
  476. UInt p=n0+n1-NUMBER_DIGS/2; if(p<NUMBER_DIGS)t1.d[p]=x;
  477. x>>=16;
  478. }
  479. }
  480. t0.rawAdd(t1);
  481. }
  482. t0._real=(_real|N._real); T=t0;
  483. return T;
  484. }
  485. /******************************************************************************/
  486. static Bool DivModFast(Number &x, C Number &y, Number &div)
  487. {
  488. Int yd=y.digits();
  489. if( yd<=4)
  490. {
  491. if(!yd){div.zero(); return true;}
  492. Int xd=x.digits();
  493. if( xd<=4)
  494. {
  495. Bool dsign=x. sign^y.sign,
  496. msign=x. sign,
  497. dmreal=x._real;
  498. if(xd<=2 && yd<=2)
  499. {
  500. U32 _x=(U32&)x.d[0],
  501. _y=(U32&)y.d[0];
  502. div=_x/_y;
  503. x =_x%_y;
  504. }else
  505. {
  506. U64 _x=(U64&)x.d[0],
  507. _y=(U64&)y.d[0];
  508. div=_x/_y;
  509. x =_x%_y;
  510. }
  511. div.sign=dsign; div._real=dmreal;
  512. x.sign=msign; x._real=dmreal;
  513. return true;
  514. }
  515. }
  516. return false;
  517. }
  518. static void DivModSub(Number &x, C Number &y, Number &div)
  519. {
  520. if(!DivModFast(x, y, div))
  521. {
  522. UInt div_sub=0; for(; x.rawCompare(y)>=0; x.rawSub(y), div_sub++);
  523. div=div_sub;
  524. }
  525. }
  526. static void DivMod(Number &x, C Number &y, Number &div)
  527. {
  528. Number y_temp;
  529. C Number *Y;
  530. if(!y._real)
  531. {
  532. if(DivModFast(x, y, div))return;
  533. Y=&y;
  534. }else
  535. {
  536. // auto shifting for more precision
  537. Int xd=x.toReal().digits(),
  538. yd=y .digits(),
  539. m =Max(xd, yd-NUMBER_DIGS/2),
  540. l =NUMBER_DIGS-m;
  541. if(yd+l-NUMBER_DIGS/2<=0){div.zero(); return;}
  542. x. shlDig(l);
  543. Y=&y_temp.setShlDig(y, l-NUMBER_DIGS/2);
  544. }
  545. div.zero();
  546. div. sign=x. sign^y.sign;
  547. div._real=x._real;
  548. REP(NUMBER_DIGS)
  549. {
  550. Number temp; temp.setShrDig(x, i);
  551. if(temp.rawCompare(*Y)>=0)
  552. {
  553. Number bkp=temp, div_sub; DivModSub(temp, *Y, div_sub);
  554. x.rawSub(bkp.rawSub(temp).shlDig(i));
  555. div.rawAdd( div_sub.shlDig(i));
  556. }
  557. }
  558. }
  559. Number& Number::operator/=(C Number &N) {Number div; DivMod(T, N, div); T=div; return T;}
  560. Number& Number::operator%=(C Number &N) {Number div; DivMod(T, N, div); return T;}
  561. /******************************************************************************/
  562. Number& Number::operator+=(Dbl N) {return T+=Number(N);}
  563. Number& Number::operator-=(Dbl N) {return T-=Number(N);}
  564. Number& Number::operator*=(Int N) {return T*=Number(N);} Number& Number::operator*=(Dbl N) {return T*=Number(N);}
  565. Number& Number::operator/=(Int N) {return T/=Number(N);} Number& Number::operator/=(Dbl N) {return T/=Number(N);}
  566. Number& Number::operator%=(Int N) {return T%=Number(N);}
  567. /******************************************************************************/
  568. Number operator+(C Number &a, C Number &b){return Number(a)+=b;} Number operator+(C Number &a, Int b) {return Number(a)+=b;} Number operator+(Int a, C Number &b) {return Number(a)+=b;} Number operator+(C Number &a, Dbl b) {return Number(a)+=b;} Number operator+(Dbl a, C Number &b) {return Number(a)+=b;}
  569. Number operator-(C Number &a, C Number &b){return Number(a)-=b;} Number operator-(C Number &a, Int b) {return Number(a)-=b;} Number operator-(Int a, C Number &b) {return Number(a)-=b;} Number operator-(C Number &a, Dbl b) {return Number(a)-=b;} Number operator-(Dbl a, C Number &b) {return Number(a)-=b;}
  570. Number operator*(C Number &a, C Number &b){return Number(a)*=b;} Number operator*(C Number &a, Int b) {return Number(a)*=b;} Number operator*(Int a, C Number &b) {return Number(a)*=b;} Number operator*(C Number &a, Dbl b) {return Number(a)*=b;} Number operator*(Dbl a, C Number &b) {return Number(a)*=b;}
  571. Number operator/(C Number &a, C Number &b){return Number(a)/=b;} Number operator/(C Number &a, Int b) {return Number(a)/=b;} Number operator/(Int a ,C Number &b) {return Number(a)/=b;} Number operator/(C Number &a, Dbl b) {return Number(a)/=b;} Number operator/(Dbl a, C Number &b) {return Number(a)/=b;}
  572. Number operator%(C Number &a, C Number &b){return Number(a)%=b;}
  573. /******************************************************************************/
  574. Number& Number::sqr()
  575. {
  576. Number t0,t1;
  577. t0.zero();
  578. FREPD(n0, NUMBER_DIGS)
  579. {
  580. t1.zero();
  581. UInt x=0;
  582. if(_real)
  583. {
  584. FREPD(n1, NUMBER_DIGS)
  585. {
  586. x+=d[n0]*d[n1];
  587. UInt p=n0+n1-NUMBER_DIGS/2; if(p<NUMBER_DIGS)t1.d[p]=x;
  588. x>>=16;
  589. }
  590. }else
  591. {
  592. FREPD(n1, NUMBER_DIGS)
  593. {
  594. if(n0+n1>=NUMBER_DIGS)break;
  595. x+=d[n0]*d[n1];
  596. t1.d[n0+n1]=x;
  597. x>>=16;
  598. }
  599. }
  600. t0.rawAdd(t1);
  601. }
  602. t0._real=_real; T=t0;
  603. return T;
  604. }
  605. Number& Number::sqrt()
  606. {
  607. if(Int digits=T.digits())
  608. {
  609. Int shl=0;
  610. if(_real) // auto shifting for more precision
  611. {
  612. shl=((NUMBER_DIGS-digits)&~1);
  613. shlDig(shl); digits+=shl;
  614. shl=NUMBER_DIGS/4 - (shl>>1);
  615. }
  616. Number res=0, one=0; digits--;
  617. UInt bit=1<<14; for(UInt dig=d[digits]; bit>dig; )bit>>=2; one.d[digits]=bit;
  618. for(; one.digits(); )
  619. {
  620. Number res_one=res; res_one.rawAdd(one);
  621. if(rawCompare(res_one)>=0)
  622. {
  623. rawSub(res_one);
  624. res=res_one.rawAdd(one);
  625. }
  626. res>>=1;
  627. one>>=2;
  628. }
  629. res.shlDig(shl)._real=_real;
  630. T=res;
  631. }
  632. return T;
  633. }
  634. /******************************************************************************/
  635. Number Number2::length2 ()C {return x*x + y*y ;}
  636. Number Number3::length2 ()C {return x*x + y*y + z*z ;}
  637. Number Number2::length ()C {return (x*x + y*y ).sqrt();}
  638. Number Number3::length ()C {return (x*x + y*y + z*z).sqrt();}
  639. Number Number2::normalize() {Number l=length(); T/=l; return l;}
  640. Number Number3::normalize() {Number l=length(); T/=l; return l;}
  641. /******************************************************************************/
  642. #pragma runtime_checks("", restore)
  643. }
  644. /******************************************************************************/