_real.c
上传用户:gzelex
上传日期:2007-01-07
资源大小:707k
文件大小:16k
开发平台:

MultiPlatform

  1. /*******************************************************************************
  2. +
  3. +  LEDA-R  3.2.3
  4. +
  5. +  _real.c
  6. +
  7. +  Copyright (c) 1995  by  Max-Planck-Institut fuer Informatik
  8. +  Im Stadtwald, 66123 Saarbruecken, Germany     
  9. +  All rights reserved.
  10. *******************************************************************************/
  11. /* This file has been automatically generated from "real.w"
  12.    by CTANGLE (Version 3.1 [km2c]) */
  13. /*12:*/
  14. #include <LEDA/real.h>
  15. /*16:*/
  16. #include <math.h>
  17. /*:16*/
  18. /*14:*/
  19. enum constructortype{DOUBLE= 0,BIGFLOAT= 1,NEGATION= 2,
  20. SQUAREROOT= 3,ADDITION= 4,SUBTRACTION= 5,MULTIPLICATION= 6,
  21. DIVISION= 7};
  22. struct app_bf
  23. {bigfloat NUM_BF;
  24. bigfloat ERROR_BF;
  25. app_bf(){}
  26. app_bf(const bigfloat&x,const bigfloat&error_x)
  27. {NUM_BF= x;ERROR_BF= error_x;}
  28. };
  29. /*:14*/
  30. /*3:*/
  31. const double eps= ldexp(1,-53);/* $eps = 2^{-53}$ */
  32. const double correction= 1+8*eps;
  33. const double MaxError= ldexp(1,900);/* $2^{900}$ */
  34. const double MinDbl= ldexp(1,-1022);
  35. const double MaxDbl= ldexp(2-ldexp(1,-52),1023);
  36. /*:3*//*4:*/
  37. const bigfloat zero= double(0);
  38. const bigfloat one= double(0);
  39. const bigfloat two= double(2);
  40. const bigfloat onehalf= double(1)/double(2);
  41. const bigfloat onefourth= double(1)/double(4);
  42. const bigfloat oneeighth= double(1)/double(8);
  43. const bigfloat eps_prec= eps;
  44. const bigfloat correction_bf= correction;
  45. /*:4*/
  46. /*15:*/
  47. class real_rep
  48. {
  49. friend class real;
  50. /*9:*/
  51. friend real operator+(const real&,const real&);
  52. /*{Mbinop addition
  53. }*/
  54. friend real operator-(const real&,const real&);
  55. /*{Mbinop subtraction
  56. }*/
  57. friend real operator*(const real&,const real&);
  58. /*{Mbinop multiplication
  59. }*/
  60. friend real operator/(const real&,const real&);
  61. /*{Mbinop division
  62. }*/
  63. friend real operator-(const real&);
  64. /*{Munop negation
  65. }*/
  66. friend real sqrt(const real&);
  67. /*{Mop squareroot operation
  68. }*/
  69. /*:9*/
  70. double NUM;
  71. double ERROR;
  72. app_bf*APP_BF_PTR;
  73. constructortype CON;
  74. real_rep*OP1,*OP2;
  75. int count;
  76. real_rep(double= 0);
  77. real_rep(const bigfloat&);
  78. real_rep(const bigrational&);
  79. ~real_rep();
  80. LEDA_MEMORY(real_rep)
  81. inline bigfloat&num_bf() const {return APP_BF_PTR->NUM_BF;}
  82. inline bigfloat&error_bf() const {return APP_BF_PTR->ERROR_BF;}
  83. void init_app_bf();
  84. void adjust_dbl();
  85. int sign();
  86. int sign(const bigfloat&);
  87. inline void improve(const bigfloat&);
  88. inline void improve(long k);
  89. inline void compute(long);
  90. /*43:*/
  91. friend void Mignotte_parameters(const real_rep&,integer&,integer&);
  92. /*:43*/
  93. };
  94. /*:15*/
  95. // INSERTED 
  96. GenPtr real::copy() const { PTR->count++; return PTR; }
  97. void   real::clear()      { if (PTR && --(PTR->count)==0) delete PTR; }
  98. /*17:*/
  99. real::real(){PTR= new real_rep(0);}
  100. real::real(double x){PTR= new real_rep(x);}
  101. real::real(int x){PTR= new real_rep(double(x));}
  102. real::real(const bigrational&x){PTR= new real_rep(x);}
  103. real::real(const bigfloat&x){PTR= new real_rep(x);}
  104. real::real(const integer&x){PTR= new real_rep(bigfloat(x));}
  105. real::real(real_rep&x_rep){PTR= &x_rep;}
  106. real::real(const real&x){PTR= x.PTR;x.PTR->count++;}
  107. real&real::operator= (const real&x)
  108. {x.PTR->count++;
  109. if(PTR && --PTR->count==0)delete PTR;
  110. PTR= x.PTR;
  111. return(*this);
  112. }
  113. /*:17*//*18:*/
  114. real_rep::real_rep(double x)
  115. {APP_BF_PTR= nil;count= 1;
  116. OP1= OP2= nil;
  117. NUM= x;ERROR= 0;CON= DOUBLE;
  118. }
  119. real_rep::real_rep(const bigfloat&x)
  120. {APP_BF_PTR= new app_bf(x,0);count= 1;
  121. OP1= nil;OP2= nil;CON= BIGFLOAT;
  122. adjust_dbl();
  123. }
  124. real_rep::real_rep(const bigrational&x)
  125. {
  126. APP_BF_PTR= nil;count= 1;
  127. OP1= new real_rep(bigfloat(x.numerator()));
  128. OP2= new real_rep(bigfloat(x.denominator()));
  129. CON= DIVISION;
  130. adjust_dbl();
  131. }
  132. /*:18*//*19:*/
  133. real::~real()
  134. {PTR->count--;
  135. if(PTR->count==0)
  136. delete PTR;
  137. }
  138. real_rep::~real_rep()
  139. {
  140. if(APP_BF_PTR!=nil)
  141. delete APP_BF_PTR;
  142. if((OP1!=nil)&&(--OP1->count==0))
  143. delete OP1;
  144. if((OP2!=nil)&&(--OP2->count==0))
  145. delete OP2;
  146. #ifdef DEBUG_REAL
  147. APP_BF_PTR= nil;
  148. OP1= OP2= nil;
  149. #endif
  150. }
  151. /*:19*/
  152. /*20:*/
  153. void real_rep::init_app_bf()
  154. {
  155. if(APP_BF_PTR==nil)
  156. if(ERROR!=Infinity)
  157. APP_BF_PTR= 
  158. new app_bf(bigfloat(NUM),fabs(bigfloat(ERROR*NUM*correction)));
  159. else
  160. compute(52);
  161. }
  162. /*:20*//*21:*/
  163. void real_rep::adjust_dbl()
  164. {
  165. if((fabs(num_bf())>bigfloat(MaxDbl))
  166. ||(error_bf()>bigfloat(MaxDbl))
  167. )
  168. {
  169. ERROR= Infinity;NUM= 1;return;
  170. }
  171. if((num_bf()==zero)&&(error_bf()==zero))
  172. {
  173. NUM= ERROR= 0;return;
  174. }
  175. double n_head= num_bf().todouble();
  176. double e_head= error_bf().todouble();
  177. if(n_head!=0)
  178. {NUM= n_head;
  179. ERROR= eps+Max(MinDbl,e_head)/fabs(n_head);
  180. }
  181. else
  182. {NUM= e_head+2*MinDbl;
  183. ERROR= 2;
  184. }
  185. ERROR= ERROR*correction;
  186. if(ERROR>=MaxError)
  187. {NUM= 1;ERROR= Infinity;
  188. }
  189. }
  190. /*:21*//*22:*/
  191. double real::todouble()const
  192. {return PTR->NUM;}
  193. double real::get_double_error()const
  194. {return PTR->ERROR;}
  195. bigfloat real::tobigfloat()const
  196. {PTR->init_app_bf();return PTR->num_bf();}
  197. integer real::get_precision()const
  198. {PTR->init_app_bf();return-PTR->error_bf().get_exponent();}
  199. ostream&operator<<(ostream&out, const real&x)
  200. {out<<x.tobigfloat();return out;}
  201. istream&operator>>(istream&in,real&x)
  202. {
  203. double x_num;in>>x_num;
  204. x= real(x_num);return in;
  205. }
  206. /*:22*/
  207. /*23:*/
  208. real operator+(const real&x,const real&y)
  209. {
  210. real_rep&z_rep= *new real_rep();
  211. /* this represents the new |real| element |z| that we return later */
  212. z_rep.CON= ADDITION;
  213. z_rep.OP1= x.PTR;z_rep.OP2= y.PTR;
  214. z_rep.OP1->count++;z_rep.OP2->count++;
  215. /* the new element |z| now points to |x| and |y|, so their counters have
  216.        to be increased by one
  217.     */
  218. double&x_num= x.PTR->NUM;
  219. double&y_num= y.PTR->NUM;
  220. double&NUM= z_rep.NUM;
  221. NUM= x_num+y_num;/* approximation of $x+y$ */
  222. if(fabs(NUM)>MinDbl)
  223. {/* regular case */
  224. z_rep.ERROR= fabs(x_num/NUM)*x.PTR->ERROR
  225. +fabs(y_num/NUM)*y.PTR->ERROR
  226. +eps;
  227. }
  228. else
  229. {/* underflow is possible */
  230. NUM= fabs(x_num)*x.PTR->ERROR+fabs(y_num)*y.PTR->ERROR+4*MinDbl;
  231. z_rep.ERROR= 2;
  232. }
  233. z_rep.ERROR*= correction;
  234. if(!((fabs(NUM)+x.PTR->ERROR+y.PTR->ERROR<Infinity)
  235. &&(z_rep.ERROR<MaxError)
  236. )
  237. )
  238. /* if one of the quantities fabs(NUM), x.PTR->ERROR, y.PTR->ERROR, and
  239.         z_rep.ERROR is either Infinity or NaN, we set the error of the
  240.         result to Infinity
  241.      */
  242. z_rep.ERROR= Infinity;
  243. return real(z_rep);
  244. }
  245. real operator-(const real&x,const real&y)
  246. {
  247. real_rep&z_rep= *new real_rep();
  248. z_rep.CON= SUBTRACTION;
  249. z_rep.OP1= x.PTR;z_rep.OP2= y.PTR;
  250. z_rep.OP1->count++;z_rep.OP2->count++;
  251. if((x.PTR->ERROR==Infinity)||(y.PTR->ERROR==Infinity))
  252. {z_rep.ERROR= Infinity;return real(z_rep);
  253. }
  254. double x_num= x.PTR->NUM,y_num= y.PTR->NUM;
  255. double&NUM= z_rep.NUM;
  256. NUM= x_num-y_num;/* approximation of $x-y$ */
  257. if(fabs(NUM)<=MinDbl)
  258. {
  259. NUM= fabs(x_num)*x.PTR->ERROR+fabs(y_num)*y.PTR->ERROR+4*MinDbl;
  260. z_rep.ERROR= 2;
  261. }
  262. else
  263. {z_rep.ERROR= fabs(x_num/NUM)*x.PTR->ERROR
  264. +fabs(y_num/NUM)*y.PTR->ERROR
  265. +eps;
  266. }
  267. z_rep.ERROR*= correction;
  268. if(!((fabs(NUM)+x.PTR->ERROR+y.PTR->ERROR<Infinity)
  269. &&(z_rep.ERROR<MaxError)
  270. )
  271. )
  272. z_rep.ERROR= Infinity;
  273. return real(z_rep);
  274. }
  275. /*:23*//*24:*/
  276. real operator*(const real&x,const real&y)
  277. {
  278. real_rep&z_rep= *new real_rep();
  279. z_rep.CON= MULTIPLICATION;
  280. z_rep.OP1= x.PTR;z_rep.OP2= y.PTR;
  281. z_rep.OP1->count++;z_rep.OP2->count++;
  282. double&x_num= x.PTR->NUM;
  283. double&y_num= y.PTR->NUM;
  284. double&qx= x.PTR->ERROR;
  285. double&qy= y.PTR->ERROR;
  286. double&NUM= z_rep.NUM;
  287. NUM= x_num*y_num;
  288. if(!(fabs(NUM)<MinDbl))
  289. {
  290. z_rep.ERROR= qx+qy+qx*qy+eps;
  291. }
  292. else
  293. {if((x_num!=0)&&(y_num!=0))
  294. {/* underflow occurred in the computation of |z_rep.NUM| */
  295. z_rep.NUM= MinDbl*(1+qx)*(1+qy);
  296. z_rep.ERROR= 2;
  297. }
  298. else
  299. z_rep.ERROR= 0;
  300. }
  301. z_rep.ERROR*= correction;
  302. if(!((fabs(NUM)+qx+qy<Infinity)&&(z_rep.ERROR<MaxError)))
  303. z_rep.ERROR= Infinity;
  304. return real(z_rep);
  305. }
  306. /*:24*//*25:*/
  307. real operator/(const real&x,const real&y)
  308. {
  309. real_rep&z_rep= *new real_rep();
  310. z_rep.CON= DIVISION;
  311. z_rep.OP1= x.PTR;z_rep.OP2= y.PTR;
  312. z_rep.OP1->count++;z_rep.OP2->count++;
  313. double x_num= x.PTR->NUM,y_num= y.PTR->NUM;
  314. double&NUM= z_rep.NUM;
  315. if(!(y.PTR->ERROR<1))
  316. {z_rep.ERROR= Infinity;return real(z_rep);
  317. }
  318. if(y_num==0)
  319. error_handler(1,"real::operator/:Division by zero");
  320. NUM= x_num/y_num;
  321. if(fabs(NUM)>=MinDbl)
  322. z_rep.ERROR= (x.PTR->ERROR+y.PTR->ERROR)/(1-y.PTR->ERROR)
  323. +eps;
  324. else
  325. {
  326. if(x_num!=0)
  327. {
  328. NUM= MinDbl*(1+x.PTR->ERROR)/(1-y.PTR->ERROR);
  329. z_rep.ERROR= 2;
  330. }
  331. else z_rep.ERROR= 0;
  332. }
  333. z_rep.ERROR*= correction;
  334. if(!((fabs(NUM)+x.PTR->ERROR!=Infinity)||(z_rep.ERROR<MaxError)))
  335. z_rep.ERROR= Infinity;
  336. return real(z_rep);
  337. }
  338. /*:25*//*26:*/
  339. real sqrt(const real&x)
  340. {real_rep&z_rep= *new real_rep();
  341. z_rep.CON= SQUAREROOT;
  342. z_rep.OP1= x.PTR;z_rep.OP1->count++;
  343. z_rep.OP2= nil;
  344. double x_num= x.PTR->NUM;
  345. if(x.PTR->ERROR>=1)
  346. {z_rep.ERROR= Infinity;return real(z_rep);
  347. }
  348. if(x_num==0)
  349. {z_rep.NUM= z_rep.ERROR= 0;return real(z_rep);
  350. }
  351. if(x_num<0)
  352. error_handler(-1,"real::sqrt: sqrt of negative number");
  353. z_rep.NUM= sqrt(x_num);
  354. z_rep.ERROR= x.PTR->ERROR+eps;
  355. z_rep.ERROR*= correction;
  356. return real(z_rep);
  357. }
  358. /*:26*//*27:*/
  359. real operator-(const real&x)
  360. {real_rep&z_rep= *new real_rep();
  361. z_rep.CON= NEGATION;
  362. z_rep.OP1= x.PTR;z_rep.OP1->count++;z_rep.OP2= nil;
  363. z_rep.NUM= -x.PTR->NUM;z_rep.ERROR= x.PTR->ERROR;
  364. return real(z_rep);
  365. }
  366. /*:27*//*28:*/
  367. real operator+= (real&x,real&y){x= x+y;return x;}
  368. real operator-= (real&x,real&y){x= x-y;return x;}
  369. real operator*= (real&x,real&y){x= x*y;return x;}
  370. /*:28*/
  371. /*32:*/
  372. long needed_places(const bigfloat&epsilon)
  373. {return-epsilon.get_exponent().tolong();}
  374. /*:32*/
  375. /*29:*/
  376. void real::improve(const integer&prec){PTR->improve(pow2(-prec));}
  377. void real::improve(long p){PTR->improve(pow2(-p));}
  378. void real::compute_in(long p){PTR->compute(p);}
  379. void real::compute_up_to(long p)
  380. {PTR->init_app_bf();
  381. if(PTR->sign()==0)return;
  382. bigfloat q= (fabs(tobigfloat())+pow2(-get_precision()))*bigfloat(pow2(-p-1));
  383. PTR->improve(q);
  384. PTR->APP_BF_PTR->NUM_BF.round(p);
  385. PTR->APP_BF_PTR->ERROR_BF= q;
  386. PTR->adjust_dbl();
  387. }
  388. /*:29*//*30:*/
  389. void real_rep::improve(const bigfloat&q)
  390. {
  391. if(q<=zero)
  392. error_handler(-1,"real_rep::improve: quality <= 0");
  393. int signum;
  394. long p;
  395. bigfloat needed_precision,
  396. easy_value,
  397. qx,qy,
  398. y_low,
  399. x_high,x_low,
  400. qsquare;
  401. init_app_bf();
  402. if(error_bf()<=q)return;
  403. switch(CON)
  404. {
  405. case DOUBLE:case BIGFLOAT:return;
  406. case NEGATION:
  407. OP1->improve(q);
  408. num_bf()= -OP1->num_bf();
  409. break;
  410. case ADDITION:/*33:*/
  411. OP1->improve(onefourth*q);
  412. OP2->improve(onefourth*q);
  413. easy_value= OP1->num_bf()+OP2->num_bf();
  414. if(easy_value==zero)
  415. num_bf()= zero;
  416. else
  417. {
  418. needed_precision= onefourth*q/fabs(easy_value);
  419. p= needed_places(needed_precision);
  420. num_bf()= add(OP1->num_bf(),OP2->num_bf(),p);
  421. }
  422. /*:33*/
  423. ;break;
  424. case SUBTRACTION:/*34:*/
  425. OP1->improve(onefourth*q);
  426. OP2->improve(onefourth*q);
  427. easy_value= OP1->num_bf()+OP2->num_bf();
  428. if(easy_value==zero)
  429. num_bf()= 0;
  430. else
  431. {
  432. needed_precision= onefourth*q/fabs(easy_value);
  433. p= needed_places(needed_precision);
  434. num_bf()= sub(OP1->num_bf(),OP2->num_bf(),p);
  435. }
  436. /*:34*/
  437. ;break;
  438. case MULTIPLICATION:/*35:*/
  439. OP2->init_app_bf();
  440. qx= q*oneeighth/(fabs(OP2->num_bf())+OP2->error_bf());
  441. OP1->improve(qx);
  442. qy= q*oneeighth/fabs(OP1->num_bf());
  443. OP2->improve(qy);
  444. easy_value= OP1->num_bf()*OP2->num_bf();
  445. if(easy_value==zero)
  446. num_bf()= zero;
  447. else
  448. {
  449. needed_precision= q*onefourth/fabs(easy_value);
  450. p= needed_places(needed_precision);
  451. num_bf()= mul(OP1->num_bf(),OP2->num_bf(),p);
  452. }
  453. /*:35*/
  454. ;break;
  455. case DIVISION:/*36:*/
  456. signum= OP2->sign();
  457. if(signum==0)error_handler(0,"real::improve: division by zero");
  458. OP2->init_app_bf();
  459. y_low= fabs(OP2->num_bf())-error_bf();
  460. qx= q*y_low*oneeighth;
  461. OP1->improve(qx);
  462. if(OP1->num_bf()==zero)
  463. num_bf()= 0;
  464. else
  465. {
  466. qy= q*y_low*y_low*oneeighth/fabs(OP1->num_bf());
  467. OP2->improve(qy);
  468. needed_precision= q*onefourth*fabs(OP2->num_bf()/OP1->num_bf());
  469. p= needed_places(needed_precision);
  470. num_bf()= div(OP1->num_bf(),OP2->num_bf(),p);
  471. }
  472. /*:36*/
  473. ;break;
  474. case SQUAREROOT:/*37:*/
  475. OP1->init_app_bf();
  476. x_low= OP1->num_bf()-OP1->error_bf();
  477. x_high= OP1->num_bf()+OP1->error_bf();
  478. qsquare= q*q;
  479. if((x_low<=onefourth*qsquare)&&(x_high>=onehalf*qsquare))
  480. {
  481. OP1->improve(oneeighth*qsquare);
  482. x_low= OP1->num_bf()-OP1->error_bf();
  483. x_high= OP1->num_bf()+OP1->error_bf();
  484. }
  485. if(x_high<zero)
  486. error_handler(-1,"real::improve: sqrt needs an argument >= 0");
  487. if(x_low>onefourth*qsquare)
  488. {
  489. qx= onefourth*q*sqrt(x_low);
  490. OP1->improve(qx);
  491. needed_precision= onefourth*q/sqrt(x_high);
  492. p= needed_places(needed_precision);
  493. num_bf()= sqrt(fabs(OP1->num_bf()),p);
  494. }
  495. else
  496. num_bf()= 0;
  497. /*:37*/
  498. ;break;
  499. }
  500. error_bf() = q;
  501. adjust_dbl();
  502. }
  503. /*:30*//*38:*/
  504. void real_rep::compute(long p)
  505. {
  506. if(p<=0)
  507. error_handler(1,"real_rep::compute needs an argument > 0");
  508. bigfloat*x_ptr= nil,*qx_ptr= nil,*y_ptr= nil,*qy_ptr= nil;
  509. if(OP1!=nil)
  510. {OP1->compute(p);
  511. x_ptr= &(OP1->num_bf());
  512. qx_ptr= &(OP1->error_bf());
  513. }
  514. if(OP2!=nil)
  515. {OP2->compute(p);
  516. y_ptr= &(OP2->num_bf());
  517. qy_ptr= &(OP2->error_bf());
  518. }
  519. bigfloat&x= *x_ptr,&y= *y_ptr,&qx= *qx_ptr,&qy= *qy_ptr,
  520. x_low,x_high,y_low;
  521. if(APP_BF_PTR==nil)APP_BF_PTR= new app_bf();
  522. int signum;
  523. bigfloat prec= pow2(-p);
  524. switch(CON)
  525. {
  526. case DOUBLE:
  527. num_bf()= bigfloat(NUM);
  528. error_bf()= 0;break;
  529. case BIGFLOAT:break;
  530. case NEGATION:
  531. num_bf()= -x;
  532. error_bf()= qx;break;
  533. case ADDITION:
  534. num_bf()= add(x,y,p);
  535. error_bf()= fabs(num_bf())*prec+qx+qy;break;
  536. case SUBTRACTION:
  537. num_bf()= sub(x,y,p);
  538. error_bf()= fabs(num_bf())*prec+qx+qy;break;
  539. case MULTIPLICATION:
  540. num_bf()= mul(x,y,p);
  541. error_bf()= fabs(num_bf())*prec+fabs(x)*qy+fabs(y)*qx+qx*qy;
  542. break;
  543. case DIVISION:
  544. if(qy>=fabs(y))
  545. {signum= OP2->sign();
  546. if(signum==0)error_handler(-2,"real::compute: division by zero");
  547. }
  548. y_low= fabs(OP2->num_bf())-OP2->error_bf();
  549. num_bf()= div(x,y,p);
  550. error_bf()= fabs(num_bf())*prec+(qy*fabs(num_bf())+qx)/y_low;
  551. break;
  552. case SQUAREROOT:
  553. x_low= x-qx;x_high= x+qx;
  554. if(x_high<zero)
  555. error_handler(-1,"real::compute: squareroot needs argument >= 0");
  556. if(x_low>zero)
  557. {
  558. num_bf()= sqrt(x,p);
  559. error_bf()= num_bf()*prec+qx/sqrt(x_low);
  560. }
  561. else
  562. {
  563. num_bf()= sqrt(qx,p);
  564. error_bf()= two*num_bf();
  565. }
  566. }
  567. error_bf()= error_bf()*bigfloat(correction);
  568. adjust_dbl();
  569. }
  570. /*:38*/
  571. /*39:*/
  572. int sign(double x)
  573. {if(x==0)return 0;else return(x>0?1:-1);}
  574. /*:39*//*40:*/
  575. int real::sign() {return PTR->sign(0);}
  576. int real::sign(const integer&prec) {return PTR->sign(pow2(-prec));}
  577. int real::sign(long p) {return PTR->sign(pow2(-p));}
  578. int real_rep::sign() {return sign(0);}
  579. int real_rep::sign(const bigfloat&q_initial)
  580. {integer M= 0,deg= 1;
  581. bigfloat q= q_initial;
  582. /*41:*/
  583. if((ERROR!=Infinity)&&((NUM==0)||(ERROR<1)))
  584. return::sign(NUM);
  585. if((APP_BF_PTR!=nil)&&
  586. ((error_bf()==zero)||(error_bf()<fabs(num_bf())))
  587. )
  588. return::sign(num_bf());
  589. /*:41*/
  590. if(q==zero)/*45:*/
  591. Mignotte_parameters(*this,M,deg);
  592. q= pow2(-M)*correction_bf;
  593. /*:45*/
  594. /*42:*/
  595. bigfloat current_precision= eps_prec;
  596. init_app_bf();
  597. if(error_bf()<one)
  598. current_precision= error_bf()*eps_prec;
  599. improve(current_precision);
  600. while((current_precision>q)&&(error_bf()>=fabs(num_bf())))
  601. {current_precision= current_precision*current_precision;
  602. improve(current_precision);
  603. }
  604. if(fabs(num_bf())>error_bf())
  605. return::sign(num_bf());
  606. return 0;
  607. /*:42*/
  608. }
  609. /*:40*//*44:*/
  610. void Mignotte_parameters(const real_rep&x,integer&M,integer&deg)
  611. {
  612. long exp,M_int;
  613. integer M1,M2,deg1,deg2;
  614. switch(x.CON)
  615. {case DOUBLE:
  616. deg= 1;
  617. exp= bigfloat(x.NUM).get_exponent().tolong();
  618. if(x.NUM==int(x.NUM))/* x.NUM is an integer */
  619. {M= exp+1;break;}
  620. if(exp>=52)
  621. {M_int= exp+1;M= M_int;break;}
  622. if(exp<0){M_int= 52-exp;M= M_int;break;}
  623. M= 53;break;
  624. case BIGFLOAT:if(x.APP_BF_PTR->NUM_BF!=zero)
  625. M= (x.APP_BF_PTR->NUM_BF).get_exponent();
  626. else
  627. M= 0;
  628. deg= 1;break;
  629. case NEGATION:Mignotte_parameters(*x.OP1,M,deg);break;
  630. case MULTIPLICATION:case DIVISION:
  631. Mignotte_parameters(*x.OP1,M1,deg1);
  632. Mignotte_parameters(*x.OP2,M2,deg2);
  633. M= M1*deg2+M2*deg1;
  634. deg= deg1*deg2;
  635. break;
  636. case ADDITION:case SUBTRACTION:
  637. Mignotte_parameters(*x.OP1,M1,deg1);
  638. Mignotte_parameters(*x.OP2,M2,deg2);
  639. M= deg1*deg2+M1*deg2+M2*deg1;
  640. deg= deg1*deg2;
  641. break;
  642. case SQUAREROOT:
  643. Mignotte_parameters(*x.OP1,M1,deg1);
  644. M= M1;deg= deg1<<1;
  645. break;
  646. }
  647. }
  648. /*:44*//*46:*/
  649. int operator==(const real&x,const real&y)
  650. {return((y-x).sign()==0?1:0);}
  651. int operator<(const real&x,const real&y)
  652. {return((y-x).sign()>0?1:0);}
  653. int operator>(const real&x,const real&y)
  654. {return((y-x).sign()<0?1:0);}
  655. int operator<=(const real&x,const real&y)
  656. {return((y-x).sign()>=0?1:0);}
  657. int operator>=(const real&x,const real&y)
  658. {return((y-x).sign()<=0?1:0);}
  659. int operator!=(const real&x,const real&y)
  660. {return((y-x).sign()!=0?1:0);}
  661. /*:46*/
  662. /*47:*/
  663. real fabs(real&x){ if (x.sign()<0) return -x; else return x; }
  664. real sq(const real&x){return x*x;}
  665. real hypot(const real&x,const real&y){return sqrt(x*x+y*y);}
  666. real powi(const real&x,int n)
  667. {real y= x,z= 1;
  668. int n_prefix= n;
  669. while(n_prefix>0)
  670. {
  671. if(n_prefix%2)z= z*y;
  672. n_prefix= n_prefix/2;
  673. y= y*y;
  674. }
  675. return z;
  676. }
  677. /*:47*/
  678. /*:12*/