| // 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); | |
| }; |