1 /*
   2  * Copyright 2018-2020 Raffaello Giulietti
   3  *
   4  * Permission is hereby granted, free of charge, to any person obtaining a copy
   5  * of this software and associated documentation files (the "Software"), to deal
   6  * in the Software without restriction, including without limitation the rights
   7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   8  * copies of the Software, and to permit persons to whom the Software is
   9  * furnished to do so, subject to the following conditions:
  10  *
  11  * The above copyright notice and this permission notice shall be included in
  12  * all copies or substantial portions of the Software.
  13  *
  14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20  * THE SOFTWARE.
  21  */
  22 
  23 package jdk.internal.math;
  24 
  25 import java.math.BigInteger;
  26 
  27 import static java.lang.Double.*;
  28 import static java.lang.Long.numberOfTrailingZeros;
  29 import static java.lang.StrictMath.scalb;
  30 import static java.math.BigInteger.*;
  31 import static jdk.internal.math.MathUtils.*;
  32 
  33 public class MathUtilsChecker extends BasicChecker {
  34 
  35     private static final BigInteger THREE = valueOf(3);
  36 
  37     // binary constants
  38     private static final int P =
  39             numberOfTrailingZeros(doubleToRawLongBits(3)) + 2;
  40     private static final int W = (SIZE - 1) - (P - 1);
  41     private static final int Q_MIN = (-1 << W - 1) - P + 3;
  42     private static final int Q_MAX = (1 << W - 1) - P;
  43     private static final long C_MIN = 1L << P - 1;
  44     private static final long C_MAX = (1L << P) - 1;
  45 
  46     // decimal constants
  47     private static final int K_MIN = flog10pow2(Q_MIN);
  48     private static final int K_MAX = flog10pow2(Q_MAX);
  49     private static final int H = flog10pow2(P) + 2;
  50 
  51     /*
  52     Let
  53         10^(-k) = beta 2^r
  54     for the unique integer r and real beta meeting
  55         2^125 <= beta < 2^126
  56     Further, let g = g1 2^63 + g0.
  57     Checks that:
  58         2^62 <= g1 < 2^63,
  59         0 <= g0 < 2^63,
  60         g - 1 <= beta < g,    (that is, g = floor(beta) + 1)
  61     The last predicate, after multiplying by 2^r, is equivalent to
  62         (g - 1) 2^r <= 10^(-k) < g 2^r
  63     This is the predicate that will be checked in various forms.
  64      */
  65     private static void testG(int k, long g1, long g0) {
  66         // 2^62 <= g1 < 2^63, 0 <= g0 < 2^63
  67         assertTrue(g1 << 1 < 0 && g1 >= 0 && g0 >= 0, "g");
  68 
  69         BigInteger g = valueOf(g1).shiftLeft(63).or(valueOf(g0));
  70         // double check that 2^125 <= g < 2^126
  71         assertTrue(g.signum() > 0 && g.bitLength() == 126, "g");
  72 
  73         // see javadoc of MathUtils.g1(int)
  74         int r = flog2pow10(-k) - 125;
  75 
  76         /*
  77         The predicate
  78             (g - 1) 2^r <= 10^(-k) < g 2^r
  79         is equivalent to
  80             g - 1 <= 10^(-k) 2^(-r) < g
  81         When
  82             k <= 0 & r < 0
  83         all numerical subexpressions are integer-valued. This is the same as
  84             g - 1 = 10^(-k) 2^(-r)
  85          */
  86         if (k <= 0 && r < 0) {
  87             assertTrue(
  88                     g.subtract(ONE).compareTo(TEN.pow(-k).shiftLeft(-r)) == 0,
  89                     "g");
  90             return;
  91         }
  92 
  93         /*
  94         The predicate
  95             (g - 1) 2^r <= 10^(-k) < g 2^r
  96         is equivalent to
  97             g 10^k - 10^k <= 2^(-r) < g 10^k
  98         When
  99             k > 0 & r < 0
 100         all numerical subexpressions are integer-valued.
 101          */
 102         if (k > 0 && r < 0) {
 103             BigInteger pow5 = TEN.pow(k);
 104             BigInteger mhs = ONE.shiftLeft(-r);
 105             BigInteger rhs = g.multiply(pow5);
 106             assertTrue(rhs.subtract(pow5).compareTo(mhs) <= 0
 107                             && mhs.compareTo(rhs) < 0,
 108                     "g");
 109             return;
 110         }
 111 
 112         /*
 113         Finally, when
 114             k <= 0 & r >= 0
 115         the predicate
 116             (g - 1) 2^r <= 10^(-k) < g 2^r
 117         can be used straightforwardly as all numerical subexpressions are
 118         already integer-valued.
 119          */
 120         if (k <= 0) {
 121             BigInteger mhs = TEN.pow(-k);
 122             assertTrue(g.subtract(ONE).shiftLeft(r).compareTo(mhs) <= 0 &&
 123                             mhs.compareTo(g.shiftLeft(r)) < 0,
 124                     "g");
 125             return;
 126         }
 127 
 128         /*
 129         For combinatorial reasons, the only remaining case is
 130             k > 0 & r >= 0
 131         which, however, cannot arise. Indeed, the predicate
 132             (g - 1) 2^r <= 10^(-k) < g 2^r
 133         has a positive integer left-hand side and a middle side < 1,
 134         which cannot hold.
 135          */
 136         assertTrue(false, "g");
 137     }
 138 
 139     /*
 140     Verifies the soundness of the values returned by g1() and g0().
 141      */
 142     private static void testG() {
 143         for (int k = MathUtils.K_MIN; k <= MathUtils.K_MAX; ++k) {
 144             testG(k, g1(k), g0(k));
 145         }
 146     }
 147 
 148     /*
 149     Let
 150         k = floor(log10(3/4 2^e))
 151     The method verifies that
 152         k = flog10threeQuartersPow2(e),    Q_MIN <= e <= Q_MAX
 153     This range covers all binary exponents of doubles and floats.
 154 
 155     The first equation above is equivalent to
 156         10^k <= 3 2^(e-2) < 10^(k+1)
 157     Equality never holds. Henceforth, the predicate to check is
 158         10^k < 3 2^(e-2) < 10^(k+1)
 159     This will be transformed in various ways for checking purposes.
 160 
 161     For integer n > 0, let further
 162         b = len2(n)
 163     denote its length in bits. This means exactly the same as
 164         2^(b-1) <= n < 2^b
 165      */
 166     private static void testFlog10threeQuartersPow2() {
 167         // First check the case e = 1
 168         assertTrue(flog10threeQuartersPow2(1) == 0,
 169                 "flog10threeQuartersPow2");
 170 
 171         /*
 172         Now check the range Q_MIN <= e <= 0.
 173         By rewriting, the predicate to check is equivalent to
 174             3 10^(-k-1) < 2^(2-e) < 3 10^(-k)
 175         As e <= 0, it follows that 2^(2-e) >= 4 and the right inequality
 176         implies k < 0, so the powers of 10 are integers.
 177 
 178         The left inequality is equivalent to
 179             len2(3 10^(-k-1)) <= 2 - e
 180         and the right inequality to
 181             2 - e < len2(3 10^(-k))
 182         The original predicate is therefore equivalent to
 183             len2(3 10^(-k-1)) <= 2 - e < len2(3 10^(-k))
 184 
 185         Starting with e = 0 and decrementing until the lower bound, the code
 186         keeps track of the two powers of 10 to avoid recomputing them.
 187         This is easy because at each iteration k changes at most by 1. A simple
 188         multiplication by 10 computes the next power of 10 when needed.
 189          */
 190         int e = 0;
 191         int k0 = flog10threeQuartersPow2(e);
 192         assertTrue(k0 < 0, "flog10threeQuartersPow2");
 193         BigInteger l = THREE.multiply(TEN.pow(-k0 - 1));
 194         BigInteger u = l.multiply(TEN);
 195         for (;;) {
 196             assertTrue(l.bitLength() <= 2 - e & 2 - e < u.bitLength(),
 197                     "flog10threeQuartersPow2");
 198             --e;
 199             if (e < Q_MIN) {
 200                 break;
 201             }
 202             int kp = flog10threeQuartersPow2(e);
 203             assertTrue(kp <= k0, "flog10threeQuartersPow2");
 204             if (kp < k0) {
 205                 // k changes at most by 1 at each iteration, hence:
 206                 assertTrue(k0 - kp == 1, "flog10threeQuartersPow2");
 207                 k0 = kp;
 208                 l = u;
 209                 u = u.multiply(TEN);
 210             }
 211         }
 212 
 213         /*
 214         Finally, check the range 2 <= e <= Q_MAX.
 215         In predicate
 216             10^k < 3 2^(e-2) < 10^(k+1)
 217         the right inequality shows that k >= 0 as soon as e >= 2.
 218         It is equivalent to
 219             10^k / 3 < 2^(e-2) < 10^(k+1) / 3
 220         Both the powers of 10 and the powers of 2 are integers.
 221         The left inequality is therefore equivalent to
 222             floor(10^k / 3) < 2^(e-2)
 223         and thus to
 224             len2(floor(10^k / 3)) <= e - 2
 225         while the right inequality is equivalent to
 226             2^(e-2) <= floor(10^(k+1) / 3)
 227         and hence to
 228             e - 2 < len2(floor(10^(k+1) / 3))
 229         These are summarized as
 230             len2(floor(10^k / 3)) <= e - 2 < len2(floor(10^(k+1) / 3))
 231          */
 232         e = 2;
 233         k0 = flog10threeQuartersPow2(e);
 234         assertTrue(k0 >= 0, "flog10threeQuartersPow2");
 235         BigInteger l10 = TEN.pow(k0);
 236         BigInteger u10 = l10.multiply(TEN);
 237         l = l10.divide(THREE);
 238         u = u10.divide(THREE);
 239         for (;;) {
 240             assertTrue(l.bitLength() <= e - 2 & e - 2 < u.bitLength(),
 241                     "flog10threeQuartersPow2");
 242             ++e;
 243             if (e > Q_MAX) {
 244                 break;
 245             }
 246             int kp = flog10threeQuartersPow2(e);
 247             assertTrue(kp >= k0, "flog10threeQuartersPow2");
 248             if (kp > k0) {
 249                 // k changes at most by 1 at each iteration, hence:
 250                 assertTrue(kp - k0 == 1, "flog10threeQuartersPow2");
 251                 k0 = kp;
 252                 u10 = u10.multiply(TEN);
 253                 l = u;
 254                 u = u10.divide(THREE);
 255             }
 256         }
 257     }
 258 
 259     /*
 260     Let
 261         k = floor(log10(2^e))
 262     The method verifies that
 263         k = flog10pow2(e),    Q_MIN <= e <= Q_MAX
 264     This range covers all binary exponents of doubles and floats.
 265 
 266     The first equation above is equivalent to
 267         10^k <= 2^e < 10^(k+1)
 268     Equality holds iff e = k = 0.
 269     Henceforth, the predicates to check are equivalent to
 270         k = 0,    if e = 0
 271         10^k < 2^e < 10^(k+1),    otherwise
 272     The latter will be transformed in various ways for checking purposes.
 273 
 274     For integer n > 0, let further
 275         b = len2(n)
 276     denote its length in bits. This means exactly the same as
 277         2^(b-1) <= n < 2^b
 278      */
 279     private static void testFlog10pow2() {
 280         // First check the case e = 0
 281         assertTrue(flog10pow2(0) == 0, "flog10pow2");
 282 
 283         /*
 284         Now check the range F * Q_MIN <= e < 0.
 285         By inverting all quantities, the predicate to check is equivalent to
 286             10^(-k-1) < 2^(-e) < 10^(-k)
 287         As e < 0, it follows that 2^(-e) >= 2 and the right inequality
 288         implies k < 0.
 289         The left inequality means exactly the same as
 290             len2(10^(-k-1)) <= -e
 291         Similarly, the right inequality is equivalent to
 292             -e < len2(10^(-k))
 293         The original predicate is therefore equivalent to
 294             len2(10^(-k-1)) <= -e < len2(10^(-k))
 295         The powers of 10 are integers because k < 0.
 296 
 297         Starting with e = -1 and decrementing towards the lower bound, the code
 298         keeps track of the two powers of 10 so as to avoid recomputing them.
 299         This is easy because at each iteration k changes at most by 1. A simple
 300         multiplication by 10 computes the next power of 10 when needed.
 301          */
 302         int e = -1;
 303         int k = flog10pow2(e);
 304         assertTrue(k < 0, "flog10pow2");
 305         BigInteger l = TEN.pow(-k - 1);
 306         BigInteger u = l.multiply(TEN);
 307         for (;;) {
 308             assertTrue(l.bitLength() <= -e & -e < u.bitLength(),
 309                     "flog10pow2");
 310             --e;
 311             if (e < Q_MIN) {
 312                 break;
 313             }
 314             int kp = flog10pow2(e);
 315             assertTrue(kp <= k, "flog10pow2");
 316             if (kp < k) {
 317                 // k changes at most by 1 at each iteration, hence:
 318                 assertTrue(k - kp == 1, "flog10pow2");
 319                 k = kp;
 320                 l = u;
 321                 u = u.multiply(TEN);
 322             }
 323         }
 324 
 325         /*
 326         Finally, in a similar vein, check the range 0 <= e <= Q_MAX.
 327         In predicate
 328             10^k < 2^e < 10^(k+1)
 329         the right inequality shows that k >= 0.
 330         The left inequality means the same as
 331             len2(10^k) <= e
 332         and the right inequality holds iff
 333             e < len2(10^(k+1))
 334         The original predicate is thus equivalent to
 335             len2(10^k) <= e < len2(10^(k+1))
 336         As k >= 0, the powers of 10 are integers.
 337          */
 338         e = 1;
 339         k = flog10pow2(e);
 340         assertTrue(k >= 0, "flog10pow2");
 341         l = TEN.pow(k);
 342         u = l.multiply(TEN);
 343         for (;;) {
 344             assertTrue(l.bitLength() <= e & e < u.bitLength(),
 345                     "flog10pow2");
 346             ++e;
 347             if (e > Q_MAX) {
 348                 break;
 349             }
 350             int kp = flog10pow2(e);
 351             assertTrue(kp >= k, "flog10pow2");
 352             if (kp > k) {
 353                 // k changes at most by 1 at each iteration, hence:
 354                 assertTrue(kp - k == 1, "flog10pow2");
 355                 k = kp;
 356                 l = u;
 357                 u = u.multiply(TEN);
 358             }
 359         }
 360     }
 361 
 362     /*
 363     Let
 364         k = floor(log2(10^e))
 365     The method verifies that
 366         k = flog2pow10(e),    -K_MAX <= e <= -K_MIN
 367     This range covers all decimal exponents of doubles and floats.
 368 
 369     The first equation above is equivalent to
 370         2^k <= 10^e < 2^(k+1)
 371     Equality holds iff e = 0, implying k = 0.
 372     Henceforth, the equivalent predicates to check are
 373         k = 0,    if e = 0
 374         2^k < 10^e < 2^(k+1),    otherwise
 375     The latter will be transformed in various ways for checking purposes.
 376 
 377     For integer n > 0, let further
 378         b = len2(n)
 379     denote its length in bits. This means exactly the same as
 380         2^(b-1) <= n < 2^b
 381     */
 382     private static void testFlog2pow10() {
 383         // First check the case e = 0
 384         assertTrue(flog2pow10(0) == 0, "flog2pow10");
 385 
 386         /*
 387         Now check the range K_MIN <= e < 0.
 388         By inverting all quantities, the predicate to check is equivalent to
 389             2^(-k-1) < 10^(-e) < 2^(-k)
 390         As e < 0, this leads to 10^(-e) >= 10 and the right inequality implies
 391         k <= -4.
 392         The above means the same as
 393             len2(10^(-e)) = -k
 394         The powers of 10 are integer values since e < 0.
 395          */
 396         int e = -1;
 397         int k0 = flog2pow10(e);
 398         assertTrue(k0 <= -4, "flog2pow10");
 399         BigInteger l = TEN;
 400         for (;;) {
 401             assertTrue(l.bitLength() == -k0, "flog2pow10");
 402             --e;
 403             if (e < -K_MAX) {
 404                 break;
 405             }
 406             k0 = flog2pow10(e);
 407             l = l.multiply(TEN);
 408         }
 409 
 410         /*
 411         Finally check the range 0 < e <= K_MAX.
 412         From the predicate
 413             2^k < 10^e < 2^(k+1)
 414         as e > 0, it follows that 10^e >= 10 and the right inequality implies
 415         k >= 3.
 416         The above means the same as
 417             len2(10^e) = k + 1
 418         The powers of 10 are all integer valued, as e > 0.
 419          */
 420         e = 1;
 421         k0 = flog2pow10(e);
 422         assertTrue(k0 >= 3, "flog2pow10");
 423         l = TEN;
 424         for (;;) {
 425             assertTrue(l.bitLength() == k0 + 1, "flog2pow10");
 426             ++e;
 427             if (e > -K_MIN) {
 428                 break;
 429             }
 430             k0 = flog2pow10(e);
 431             l = l.multiply(TEN);
 432         }
 433     }
 434 
 435     private static void testBinaryConstants() {
 436         assertTrue((long) (double) C_MIN == C_MIN, "C_MIN");
 437         assertTrue((long) (double) C_MAX == C_MAX, "C_MAX");
 438         assertTrue(scalb(1.0, Q_MIN) == MIN_VALUE, "MIN_VALUE");
 439         assertTrue(scalb((double) C_MIN, Q_MIN) == MIN_NORMAL, "MIN_NORMAL");
 440         assertTrue(scalb((double) C_MAX, Q_MAX) == MAX_VALUE, "MAX_VALUE");
 441     }
 442 
 443     private static void testDecimalConstants() {
 444         assertTrue(K_MIN == MathUtils.K_MIN, "K_MIN");
 445         assertTrue(K_MAX == MathUtils.K_MAX, "K_MAX");
 446         assertTrue(H == MathUtils.H, "H");
 447     }
 448 
 449     private static void testPow10() {
 450         int e = 0;
 451         long pow = 1;
 452         for (; e <= H; e += 1, pow *= 10) {
 453             assertTrue(pow == pow10(e), "pow10");
 454         }
 455     }
 456 
 457     public static void test() {
 458         testBinaryConstants();
 459         testFlog10pow2();
 460         testFlog10threeQuartersPow2();
 461         testDecimalConstants();
 462         testFlog2pow10();
 463         testPow10();
 464         testG();
 465     }
 466 
 467     public static void main(String[] args) {
 468         test();
 469     }
 470 
 471 }