7 #include "cl_rational.h"
14 #include "cl_integer.h"
18 double cl_double_approx (const cl_RA& x)
20 // Method: same as cl_RA_to_DF().
23 return cl_double_approx(x);
27 union { dfloat eksplicit; double machine_double; } u;
28 var cl_I a = numerator(x); // +/- a
29 var const cl_I& b = denominator(x); // b
30 var cl_signean sign = -(cl_signean)minusp(a); // Vorzeichen
31 if (!(sign==0)) { a = -a; } // Betrag nehmen, liefert a
32 var sintL lendiff = (sintL)integer_length(a) // (integer-length a)
33 - (sintL)integer_length(b); // (integer-length b)
34 if (lendiff > DF_exp_high-DF_exp_mid) // Exponent >= n-m > Obergrenze ?
36 #if (cl_word_size==64)
38 ((sint64)sign & bit(63))
39 | ((uint64)(bit(DF_exp_len)-1) << DF_mant_len); // Infinity
42 ((sint32)sign & bit(31))
43 | ((uint32)(bit(DF_exp_len)-1) << (DF_mant_len-32)); // Infinity
46 return u.machine_double;
48 if (lendiff < DF_exp_low-DF_exp_mid-2) // Exponent <= n-m+2 < Untergrenze ?
50 #if (cl_word_size==64)
51 u.eksplicit = ((sint64)sign & bit(63)); // 0.0
53 u.eksplicit.semhi = ((sint32)sign & bit(31)); // 0.0
56 return u.machine_double;
60 if (lendiff >= DF_mant_len+2)
62 { nenner = ash(b,lendiff - (DF_mant_len+2)); // (ash b n-m-54)
66 { zaehler = ash(a,(DF_mant_len+2) - lendiff); // (ash a -n+m+54)
69 // Division zaehler/nenner durchführen:
70 var cl_I_div_t q_r = cl_divide(zaehler,nenner);
71 var cl_I& q = q_r.quotient;
72 var cl_I& r = q_r.remainder;
73 // 2^53 <= q < 2^55, also ist q Bignum mit ceiling(55/intDsize) Digits.
74 var const uintD* ptr = BN_MSDptr(q);
75 #if (cl_word_size==64)
76 var uint64 mant = get_max64_Dptr(55,ptr);
77 if (mant >= bit(DF_mant_len+2))
78 // 2^54 <= q < 2^55, schiebe um 2 Bits nach rechts
79 { var uint64 rounding_bits = mant & (bit(2)-1);
80 lendiff = lendiff+1; // Exponent := n-m+1
82 if ( (rounding_bits < bit(1)) // 00,01 werden abgerundet
83 || ( (rounding_bits == bit(1)) // 10
84 && (eq(r,0)) // und genau halbzahlig (r=0)
85 && ((mant & bit(0)) ==0) // -> round-to-even
94 { var uint64 rounding_bit = mant & bit(0);
96 if ( (rounding_bit == 0) // 0 wird abgerundet
97 || ( (eq(r,0)) // genau halbzahlig (r=0)
98 && ((mant & bit(0)) ==0) // -> round-to-even
108 if (mant >= bit(DF_mant_len+1)) // rounding overflow?
109 { mant = mant>>1; lendiff = lendiff+1; }
112 if (lendiff < (sintL)(DF_exp_low-DF_exp_mid))
113 { u.eksplicit = ((sint64)sign & bit(63)); } // 0.0
114 else if (lendiff > (sintL)(DF_exp_high-DF_exp_mid))
116 ((sint64)sign & bit(63))
117 | ((uint64)(bit(DF_exp_len)-1) << DF_mant_len); // Infinity
121 ((sint64)sign & bit(63)) /* Vorzeichen */
122 | ((uint64)(lendiff+DF_exp_mid) << DF_mant_len) /* Exponent */
123 | ((uint64)mant & (bit(DF_mant_len)-1)); /* Mantisse */
125 return u.machine_double;
127 var uint32 manthi = get_max32_Dptr(23,ptr);
128 var uint32 mantlo = get_32_Dptr(ptr mspop ceiling(23,intDsize));
129 if (manthi >= bit(DF_mant_len-32+2))
130 // 2^54 <= q < 2^55, schiebe um 2 Bits nach rechts
131 { var uintL rounding_bits = mantlo & (bit(2)-1);
132 lendiff = lendiff+1; // Exponent := n-m+1
133 mantlo = (mantlo >> 2) | (manthi << 30); manthi = manthi >> 2;
134 if ( (rounding_bits < bit(1)) // 00,01 werden abgerundet
135 || ( (rounding_bits == bit(1)) // 10
136 && (eq(r,0)) // und genau halbzahlig (r=0)
137 && ((mantlo & bit(0)) ==0) // -> round-to-even
146 { var uintL rounding_bit = mantlo & bit(0);
147 mantlo = (mantlo >> 1) | (manthi << 31); manthi = manthi >> 1;
148 if ( (rounding_bit == 0) // 0 wird abgerundet
149 || ( (eq(r,0)) // genau halbzahlig (r=0)
150 && ((mantlo & bit(0)) ==0) // -> round-to-even
162 if (manthi >= bit(DF_mant_len-32+1)) // rounding overflow?
163 { manthi = manthi>>1; lendiff = lendiff+1; }
167 if (lendiff < (sintL)(DF_exp_low-DF_exp_mid))
168 { u.eksplicit.semhi = ((sint32)sign & bit(31)); // 0.0
171 else if (lendiff > (sintL)(DF_exp_high-DF_exp_mid))
172 { u.eksplicit.semhi =
173 ((sint32)sign & bit(31))
174 | ((uint32)(bit(DF_exp_len)-1) << (DF_mant_len-32)); // Infinity
178 { u.eksplicit.semhi =
179 ((sint32)sign & bit(31)) /* Vorzeichen */
180 | ((uint32)(lendiff+DF_exp_mid) << (DF_mant_len-32)) /* Exponent */
181 | ((uint32)manthi & (bit(DF_mant_len-32)-1)); /* Mantisse */
182 u.eksplicit.mlo = mantlo;
184 return u.machine_double;