// Implement WorstCase functions to compute the worst case for x mod C, with // the exponent of x ranges from emin to emax, and precision of x is p. // Adapted to Sollya from the Maple function in // J-M. Muller, "Elementary Functions", 3rd ed, Section 11.3.2. // // Some examples: // // 1) Worst case for trig range reduction fast passes: // // Single precision // > WorstCase(24, -6, 32, pi/32, 128); // numbermin : 10741887 // expmin : 7 // Worst case: 0x1.47d0fep30 // numberofdigits : -32.888 // // Double precision // > WorstCase(53, -8, 32, pi/128, 256); // numbermin : 6411027962775774 // expmin : -53 // Worst case: 0x1.6c6cbc45dc8dep-1 // numberofdigits : -66.4867 // // 2) Worst case for exponential function range reduction: // // Single precision // > WorstCase(24, 1, 8, log(2), 128); // numbermin : 2907270 // expmin : -22 // Worst case: 0x1.62e43p-1 // numberofdigits : -28.9678 // // Double precision // > WorstCase(53, 0, 11, log(2), 128); // numbermin : 7804143460206699 // expmin : -51 // Worst case: 0x1.bb9d3beb8c86bp1 // numberofdigits : -57.4931 // verbosity=0; procedure WorstCase(p, emin, emax, C, ndigits) { epsilonmin = 12345.0; Digits = ndigits; powerofBoverC = 2^(emin - p) / C; for e from emin - p + 1 to emax - p + 1 do { powerofBoverC = 2 * powerofBoverC; a = floor(powerofBoverC); Plast = a; r = round(1/(powerofBoverC - a), ndigits, RN); a = floor(r); Qlast = 1; Q = a; P = Plast * a + 1; while (Q < 2^p - 1) do { r = round(1/(r - a), ndigits, RN); a = floor(r); NewQ = Q * a + Qlast; NewP = P * a + Plast; Qlast = Q; Plast = P; Q = NewQ; P = NewP; }; epsilon = C * abs(Plast - Qlast * powerofBoverC); if (epsilon < epsilonmin) then { epsilonmin = epsilon; numbermin = Qlast; expmin = e; }; }; display=decimal!; print("numbermin : ", numbermin); print("expmin : ", expmin); display=hexadecimal!; print("Worst case: ", numbermin * 2^expmin); display=decimal!; ell = round(log2(epsilonmin), ndigits, RN); print("numberofdigits : ", ell); };