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

MultiPlatform

  1. /*******************************************************************************
  2. +
  3. +  LEDA-R  3.2.3
  4. +
  5. +  floatf.h
  6. +
  7. +  Copyright (c) 1995  by  Max-Planck-Institut fuer Informatik
  8. +  Im Stadtwald, 66123 Saarbruecken, Germany     
  9. +  All rights reserved.
  10. *******************************************************************************/
  11. #ifndef LEDA_FFLOAT_H
  12. #define LEDA_FFLOAT_H
  13. #include <LEDA/basic.h>
  14. #include <LEDA/integer.h>
  15. #include <math.h>
  16. /*{Manpage {floatf} {} {A Floating Point Filter} }*/ 
  17. const int NO_IDEA = 2;
  18. const double eps0 = ldexp(1,-53);   // eps0 = 2^-53
  19. class floatf {
  20. /*{Mdefinition
  21. The type $floatf$ provides a clean and efficient way to approximately
  22. compute with large integers. Consider an expression $E$ with integer
  23. operands and operators $+,-$, and $*$, and suppose that we want
  24. to determine the sign of $E$. In general, the integer arithmetic
  25. provided by our machines does not suffice to evaluate $E$ since intermediate
  26. results might overflow. Resorting to arbitrary precision integer
  27. arithmetic is a costly process. An alternative is to evaluate the 
  28. expression using floating point arithmetic, i.e., to convert the
  29. operands to doubles and to use floating-point addition, subtraction,
  30. and multiplication. Of course, only an approximation $tilde{E}$ of
  31. the true value $E$ is computed. However, $tilde{E}$ might still be
  32. able to tell us something about the sign of $E$. If $tilde{E}$ is far
  33. away from zero (the forward error analysis carried out in the next
  34. section gives a precise meaning to "far away") then the 
  35. signs of $tilde{E}$ and $E$ 
  36. agree and if $tilde{E}$ is zero then we may be able to conclude under
  37. certain circumstances that $E$ is zero. Again, forward error analysis
  38. can be used to say what `certain circumstances' are. The type $floatf$
  39. encapsulates this kind of approximate integer arithmetic. Any
  40. integer (= object of type $integer$) can be converted to a $floatf$;
  41. $floatf$s can be added, subtracted, multiplied, and their sign
  42. can be computed: for any $floatf$ $x$ the function $Sign(x)$ returns 
  43. either the sign of $x$ ($-1$ if $x < 0$, $0$ if $x = 0$, and $+1$ 
  44. if $x > 0$) or the special value $NO_IDEA$.
  45. If $x$ approximates $X$, i.e., $X$ is the integer value obtained by an 
  46. exact computation, then $Sign(x) != NO_IDEA$ implies that $Sign(x)$ 
  47. is actually the sign of $X$ if $Sign(x) = NO_IDEA$ then no claim is made 
  48. about the sign of $X$.  }*/
  49.   double num;
  50.   double mes;
  51.   float  ind;
  52. floatf(double d, double m, float i) { num = d; mes = m; ind = i;}
  53. public:
  54. /*{Mcreation x }*/
  55. floatf() { num = 0; mes = 1; ind = 0.5; }
  56. /*{Mcreate   introduces a variable var of type name and initializes
  57.               it with zero. }*/
  58. floatf(integer i) 
  59. { num = i.todouble();
  60.   mes = ldexp(1, log(abs(i)+1) + 1);
  61.   ind = 0.5;
  62.  }
  63. /*{Mcreate   introduces a variable var of type name and initializes
  64.               it with integer $i$. }*/
  65. /*{Moperations 2 4 }*/
  66. operator double() const { return num; }
  67. friend floatf operator+(const floatf& a, const floatf& b)
  68. { return floatf(a.num + b.num, 2 * ((a.mes > b.mes) ? a.mes : b.mes),
  69.                               (a.ind + b.ind + 1)/2); }
  70. /*{Mbinopfunc   Addition. }*/
  71. friend floatf operator-(const floatf& a, const floatf& b)
  72. { return floatf(a.num - b.num, 2 * ((a.mes > b.mes) ? a.mes : b.mes),
  73.                               (a.ind + b.ind + 1)/2); }
  74. /*{Mbinopfunc   Subtraction. }*/
  75. friend floatf operator*(const floatf& a, const floatf& b)
  76. { return floatf(a.num * b.num, a.mes * b.mes, a.ind + b.ind + 0.5 ); }
  77. /*{Mbinopfunc   Multiplication. }*/
  78. friend int Sign(const floatf& f)
  79. { double eps = f.ind * f.mes * eps0;
  80.   if (f.num >  eps)  return  1;
  81.   else
  82.   if (f.num < -eps)  return -1;
  83.   else
  84.   if (eps < 1)       return  0;
  85.   else
  86.   return NO_IDEA;
  87.  }
  88. /*{Mfunc  as described above. }*/
  89. /*{Mimplementation
  90. A $floatf$ is represented by a double (its value) and an error bound.
  91. An operation on $floatf$s performs the corresponding operation on
  92. the values and also computes the error bound for the result. For
  93. this reason the cost of a $floatf$ operation is about four times
  94. the cost of the corresponding operation on doubles. The rules 
  95. used to compute the error bounds are described in 
  96. (cite{Me-Naeher:sweep}).}*/
  97. };
  98. /*{Mexample
  99. see cite{Me-Naeher:sweep} for an application in a sweep line algorithm.
  100. }*/
  101. inline int Sign(const integer& x)  { return sign(x); }
  102. inline int Sign(double x)
  103. { if (x==0) return 0;
  104.   else return (x>0) ? 1 : -1;
  105.  }
  106. #endif