void conv(quad_float& z, const RR& a) { long old_p; static RR a_hi, a_lo; old_p = RR::prec; ConvPrec(a_hi, a, NTL_DOUBLE_PRECISION); // high order bits SubPrec(a_lo, a, a_hi, NTL_DOUBLE_PRECISION); // low order bits z = to_quad_float(a_hi.x)*power2_quad_float(a_hi.e) + to_quad_float(a_lo.x)*power2_quad_float(a_lo.e); }
quad_float exp(const quad_float& x) { // New version 97 Aug 05 /* ! Calculate a quadruple-precision exponential ! Method: ! x x.log2(e) nint[x.log2(e)] + frac[x.log2(e)] ! e = 2 = 2 ! ! iy fy ! = 2 . 2 ! Then ! fy y.loge(2) ! 2 = e ! ! Now y.loge(2) will be less than 0.3466 in absolute value. ! This is halved and a Pade aproximation is used to approximate e^x over ! the region (-0.1733, +0.1733). This approximation is then squared. */ if (x.hi<DBL_MIN_10_EXP*2.302585092994045684017991) return to_quad_float(0.0); if (x.hi>DBL_MAX_10_EXP*2.302585092994045684017991) { Error("exp(quad_float): overflow"); } // changed this from "const" to "static" in v5.3, since "const" // causes the initialization to be performed with *every* invocation. static quad_float Log2 = to_quad_float("0.6931471805599453094172321214581765680755"); quad_float y,temp,ysq,sum1,sum2; long iy; y=x/Log2; temp = floor(y+0.5); iy = to_long(temp); y=(y-temp)*Log2; y=ldexp(y,-1L); ysq=y*y; sum1=y*((((ysq+3960.0)*ysq+2162160.0)*ysq+302702400.0)*ysq+8821612800.0); sum2=(((90.0*ysq+110880.0)*ysq+30270240.0)*ysq+2075673600.0)*ysq+17643225600.0; /* ! sum2 + sum1 2.sum1 ! Now approximation = ----------- = 1 + ----------- = 1 + 2.temp ! sum2 - sum1 sum2 - sum1 ! ! Then (1 + 2.temp)^2 = 4.temp.(1 + temp) + 1 */ temp=sum1/(sum2-sum1); y=temp*(temp+1); y=ldexp(y,2L); return ldexp(y+1,iy); }
NTL_CLIENT int main() { quad_float a, b, c, d; quad_float::SetOutputPrecision(25); if (PrecisionOK()) cout << "Precision OK\n"; else cout << "Precision not OK\n"; cin >> a; cout << a << "\n"; cin >> b; cout << b << "\n"; c = a + b; d = a; d += b; cout << c << "\n"; cout << d << "\n"; c = a - b; d = a; d -= b; cout << c << "\n"; cout << d << "\n"; c = a * b; d = a; d *= b; cout << c << "\n"; cout << d << "\n"; c = a / b; d = a; d /= b; cout << c << "\n"; cout << d << "\n"; c = -a; cout << c << "\n"; c = sqrt(a); cout << c << "\n"; power(c, to_quad_float(10), 20); cout << c << "\n"; { long n, n1; int shamt = min(NTL_BITS_PER_LONG,2*NTL_DOUBLE_PRECISION); n = to_long((1UL << (shamt-1)) - 1UL); c = to_quad_float(n); n1 = to_long(c); if (n1 == n) cout << "long conversion OK\n"; else cout << "long conversion not OK\n"; n = to_long(1UL << (shamt-1)); c = to_quad_float(n); n1 = to_long(c); if (n1 == n) cout << "long conversion OK\n"; else cout << "long conversion not OK\n"; } { unsigned long n; ZZ n1; int shamt = min(NTL_BITS_PER_LONG,2*NTL_DOUBLE_PRECISION); n = (1UL << (shamt-1)) - 1UL; c = to_quad_float(n); n1 = to_ZZ(c); if (n1 == to_ZZ(n)) cout << "ulong conversion OK\n"; else cout << "ulong conversion not OK\n"; n = 1UL << (shamt-1); c = to_quad_float(n); n1 = to_ZZ(c); if (n1 == to_ZZ(n)) cout << "ulong conversion OK\n"; else cout << "ulong conversion not OK\n"; } }
void conv(quad_float& a,ZZ& b) { a = to_quad_float(b); }