Version in base suite: 1.7.15-1 Base version: rhino_1.7.15-1 Target version: rhino_1.7.15.1-0.1~deb13u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/r/rhino/rhino_1.7.15-1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/r/rhino/rhino_1.7.15.1-0.1~deb13u1.dsc NOTICE.txt | 27 build.gradle | 17 debian/changelog | 16 gradle.properties | 4 src/org/mozilla/javascript/DToA.java | 820 ----------- src/org/mozilla/javascript/NativeNumber.java | 138 - src/org/mozilla/javascript/ScriptRuntime.java | 23 src/org/mozilla/javascript/dtoa/Decimal.java | 306 ++++ src/org/mozilla/javascript/dtoa/DecimalFormatter.java | 163 ++ src/org/mozilla/javascript/dtoa/DoubleFormatter.java | 253 +++ src/org/mozilla/javascript/dtoa/MathUtils.java | 804 ++++++++++ src/org/mozilla/javascript/v8dtoa/CachedPowers.java | 157 -- src/org/mozilla/javascript/v8dtoa/DiyFp.java | 157 -- src/org/mozilla/javascript/v8dtoa/DoubleHelper.java | 131 - src/org/mozilla/javascript/v8dtoa/FastDtoa.java | 509 ------ src/org/mozilla/javascript/v8dtoa/FastDtoaBuilder.java | 108 - testsrc/org/mozilla/javascript/tests/NumberToStringTest.java | 89 + testsrc/test262.properties | 4 18 files changed, 1755 insertions(+), 1971 deletions(-) Unrecognised file line in .dsc: -----BEGIN PGP SIGNATURE----- dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpjbtu3aya/rhino_1.7.15-1.dsc: no acceptable signature found dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpjbtu3aya/rhino_1.7.15.1-0.1~deb13u1.dsc: no acceptable signature found diff -Nru rhino-1.7.15/NOTICE.txt rhino-1.7.15.1/NOTICE.txt --- rhino-1.7.15/NOTICE.txt 2024-05-04 00:41:43.000000000 +0000 +++ rhino-1.7.15.1/NOTICE.txt 2025-12-03 03:43:04.000000000 +0000 @@ -32,4 +32,29 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---- + +Portions of the number-to-string code are subject to the following: + + Copyright 2018-2020 Raffaello Giulietti + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + \ No newline at end of file diff -Nru rhino-1.7.15/build.gradle rhino-1.7.15.1/build.gradle --- rhino-1.7.15/build.gradle 2024-05-04 00:41:43.000000000 +0000 +++ rhino-1.7.15.1/build.gradle 2025-12-03 03:43:04.000000000 +0000 @@ -304,6 +304,7 @@ pom.withXml { def root = asNode() + root.appendNode('name', 'rhino') root.appendNode('description', """ Rhino is an open-source implementation of JavaScript written entirely in Java. It is typically embedded into Java applications to provide scripting to end users. @@ -329,6 +330,10 @@ o.appendNode("name", "The Mozilla Foundation") o.appendNode("url", "http://www.mozilla.org") + def d = root.appendNode("developers") + def dd = d.appendNode("developer") + dd.appendNode("name", "Greg Brail") + dd.appendNode("email", "gbrail@users.noreply.github.com") } } @@ -340,6 +345,7 @@ pom.withXml { def root = asNode() + root.appendNode('name', 'rhino-runtime') root.appendNode('description', """ Rhino JavaScript runtime jar, excludes tools & JSR-223 Script Engine wrapper. """) @@ -362,6 +368,11 @@ def o = root.appendNode("organization") o.appendNode("name", "The Mozilla Foundation") o.appendNode("url", "http://www.mozilla.org") + + def d = root.appendNode("developers") + def dd = d.appendNode("developer") + dd.appendNode("name", "Greg Brail") + dd.appendNode("email", "gbrail@users.noreply.github.com") } } @@ -373,6 +384,7 @@ pom.withXml { def root = asNode() + root.appendNode('name', 'rhino-engine') root.appendNode('description', """ Rhino Javascript JSR-223 Script Engine wrapper. """) @@ -401,6 +413,11 @@ rhino.appendNode("groupId", "org.mozilla") rhino.appendNode("artifactId", "rhino") rhino.appendNode("version", getVersion()) + + def d = root.appendNode("developers") + def dd = d.appendNode("developer") + dd.appendNode("name", "Greg Brail") + dd.appendNode("email", "gbrail@users.noreply.github.com") } } } diff -Nru rhino-1.7.15/debian/changelog rhino-1.7.15.1/debian/changelog --- rhino-1.7.15/debian/changelog 2024-10-23 14:34:49.000000000 +0000 +++ rhino-1.7.15.1/debian/changelog 2026-07-03 07:18:53.000000000 +0000 @@ -1,3 +1,19 @@ +rhino (1.7.15.1-0.1~deb13u1) trixie; urgency=medium + + * Non-maintainer upload. + * Rebuild for trixie. + + -- Adrian Bunk Fri, 03 Jul 2026 10:18:53 +0300 + +rhino (1.7.15.1-0.1) unstable; urgency=medium + + * Non-maintainer upload. + * New upstream release. + - CVE-2025-66453: High CPU usage and potential DoS when passing + specific numbers to toFixed() (Closes: #1121953) + + -- Adrian Bunk Tue, 30 Jun 2026 21:23:20 +0300 + rhino (1.7.15-1) unstable; urgency=medium * Team upload. diff -Nru rhino-1.7.15/gradle.properties rhino-1.7.15.1/gradle.properties --- rhino-1.7.15/gradle.properties 2024-05-04 00:41:43.000000000 +0000 +++ rhino-1.7.15.1/gradle.properties 2025-12-03 03:43:04.000000000 +0000 @@ -1,8 +1,8 @@ rootProject.name=rhino group=org.mozilla -version=1.7.15 +version=1.7.15.1 buildDir=buildGradle mavenSnapshotRepo=https://oss.sonatype.org/content/repositories/snapshots mavenReleaseRepo=https://oss.sonatype.org/service/local/staging/deploy/maven2/ org.gradle.caching=true -org.gradle.parallel=true \ No newline at end of file +org.gradle.parallel=true diff -Nru rhino-1.7.15/src/org/mozilla/javascript/DToA.java rhino-1.7.15.1/src/org/mozilla/javascript/DToA.java --- rhino-1.7.15/src/org/mozilla/javascript/DToA.java 2024-05-04 00:41:43.000000000 +0000 +++ rhino-1.7.15.1/src/org/mozilla/javascript/DToA.java 2025-12-03 03:43:04.000000000 +0000 @@ -32,14 +32,6 @@ return (char) ((digit >= 10) ? 'a' - 10 + digit : '0' + digit); } - static final int DTOSTR_STANDARD = 0, /* Either fixed or exponential format; round-trip */ - DTOSTR_STANDARD_EXPONENTIAL = 1, /* Always exponential format; round-trip */ - DTOSTR_FIXED = - 2, /* Round to digits after the decimal point; exponential if number is large */ - DTOSTR_EXPONENTIAL = 3, /* Always exponential format; significant digits */ - DTOSTR_PRECISION = - 4; /* Either fixed or exponential format; significant digits */ - private static final int Frac_mask = 0xfffff; private static final int Exp_shift = 20; private static final int Exp_msk1 = 0x100000; @@ -335,816 +327,4 @@ return buffer.toString(); } - - /* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. - * - * Inspired by "How to Print Floating-Point Numbers Accurately" by - * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101]. - * - * Modifications: - * 1. Rather than iterating, we use a simple numeric overestimate - * to determine k = floor(log10(d)). We scale relevant - * quantities using O(log2(k)) rather than O(k) multiplications. - * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't - * try to generate digits strictly left to right. Instead, we - * compute with fewer bits and propagate the carry if necessary - * when rounding the final digit up. This is often faster. - * 3. Under the assumption that input will be rounded nearest, - * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. - * That is, we allow equality in stopping tests when the - * round-nearest rule will give the same floating-point value - * as would satisfaction of the stopping test with strict - * inequality. - * 4. We remove common factors of powers of 2 from relevant - * quantities. - * 5. When converting floating-point integers less than 1e16, - * we use floating-point arithmetic rather than resorting - * to multiple-precision integers. - * 6. When asked to produce fewer than 15 digits, we first try - * to get by with floating-point arithmetic; we resort to - * multiple-precision integer arithmetic only if we cannot - * guarantee that the floating-point calculation has given - * the correctly rounded result. For k requested digits and - * "uniformly" distributed input, the probability is - * something like 10^(k-15) that we must resort to the Long - * calculation. - */ - - static int word0(double d) { - long dBits = Double.doubleToLongBits(d); - return (int) (dBits >> 32); - } - - static double setWord0(double d, int i) { - long dBits = Double.doubleToLongBits(d); - dBits = ((long) i << 32) | (dBits & 0x0FFFFFFFFL); - return Double.longBitsToDouble(dBits); - } - - static int word1(double d) { - long dBits = Double.doubleToLongBits(d); - return (int) (dBits); - } - - /* Return b * 5^k. k must be nonnegative. */ - // XXXX the C version built a cache of these - static BigInteger pow5mult(BigInteger b, int k) { - return b.multiply(BigInteger.valueOf(5).pow(k)); - } - - static boolean roundOff(StringBuilder buf) { - int i = buf.length(); - while (i != 0) { - --i; - char c = buf.charAt(i); - if (c != '9') { - buf.setCharAt(i, (char) (c + 1)); - buf.setLength(i + 1); - return false; - } - } - buf.setLength(0); - return true; - } - - /* Always emits at least one digit. */ - /* If biasUp is set, then rounding in modes 2 and 3 will round away from zero - * when the number is exactly halfway between two representable values. For example, - * rounding 2.5 to zero digits after the decimal point will return 3 and not 2. - * 2.49 will still round to 2, and 2.51 will still round to 3. */ - /* bufsize should be at least 20 for modes 0 and 1. For the other modes, - * bufsize should be two greater than the maximum number of output characters expected. */ - static int JS_dtoa( - double d, int mode, boolean biasUp, int ndigits, boolean[] sign, StringBuilder buf) { - /* Arguments ndigits, decpt, sign are similar to those - of ecvt and fcvt; trailing zeros are suppressed from - the returned string. If not null, *rve is set to point - to the end of the return value. If d is +-Infinity or NaN, - then *decpt is set to 9999. - - mode: - 0 ==> shortest string that yields d when read in - and rounded to nearest. - 1 ==> like 0, but with Steele & White stopping rule; - e.g. with IEEE P754 arithmetic , mode 0 gives - 1e23 whereas mode 1 gives 9.999999999999999e22. - 2 ==> max(1,ndigits) significant digits. This gives a - return value similar to that of ecvt, except - that trailing zeros are suppressed. - 3 ==> through ndigits past the decimal point. This - gives a return value similar to that from fcvt, - except that trailing zeros are suppressed, and - ndigits can be negative. - 4-9 should give the same return values as 2-3, i.e., - 4 <= mode <= 9 ==> same return as mode - 2 + (mode & 1). These modes are mainly for - debugging; often they run slower but sometimes - faster than modes 2-3. - 4,5,8,9 ==> left-to-right digit generation. - 6-9 ==> don't try fast floating-point estimate - (if applicable). - - Values of mode other than 0-9 are treated as mode 0. - - Sufficient space is allocated to the return value - to hold the suppressed trailing zeros. - */ - - int b2, b5, i, ieps, ilim, ilim0, ilim1, j, j1, k, k0, m2, m5, s2, s5; - char dig; - long L; - long x; - BigInteger b, b1, delta, mlo, mhi, S; - int[] be = new int[1]; - int[] bbits = new int[1]; - double d2, ds, eps; - boolean spec_case, denorm, k_check, try_quick, leftright; - - if ((word0(d) & Sign_bit) != 0) { - /* set sign for everything, including 0's and NaNs */ - sign[0] = true; - // word0(d) &= ~Sign_bit; /* clear sign bit */ - d = setWord0(d, word0(d) & ~Sign_bit); - } else sign[0] = false; - - if ((word0(d) & Exp_mask) == Exp_mask) { - /* Infinity or NaN */ - buf.append(((word1(d) == 0) && ((word0(d) & Frac_mask) == 0)) ? "Infinity" : "NaN"); - return 9999; - } - if (d == 0) { - // no_digits: - buf.setLength(0); - buf.append('0'); /* copy "0" to buffer */ - return 1; - } - - b = d2b(d, be, bbits); - if ((i = (word0(d) >>> Exp_shift1 & (Exp_mask >> Exp_shift1))) != 0) { - d2 = setWord0(d, (word0(d) & Frac_mask1) | Exp_11); - /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 - * log10(x) = log(x) / log(10) - * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) - * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) - * - * This suggests computing an approximation k to log10(d) by - * - * k = (i - Bias)*0.301029995663981 - * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); - * - * We want k to be too large rather than too small. - * The error in the first-order Taylor series approximation - * is in our favor, so we just round up the constant enough - * to compensate for any error in the multiplication of - * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, - * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, - * adding 1e-13 to the constant term more than suffices. - * Hence we adjust the constant term to 0.1760912590558. - * (We could get a more accurate k by invoking log10, - * but this is probably not worthwhile.) - */ - i -= Bias; - denorm = false; - } else { - /* d is denormalized */ - i = bbits[0] + be[0] + (Bias + (P - 1) - 1); - x = - (i > 32) - ? ((long) word0(d)) << (64 - i) | word1(d) >>> (i - 32) - : ((long) word1(d)) << (32 - i); - // d2 = x; - // word0(d2) -= 31*Exp_msk1; /* adjust exponent */ - d2 = setWord0(x, word0(x) - 31 * Exp_msk1); - i -= (Bias + (P - 1) - 1) + 1; - denorm = true; - } - /* At this point d = f*2^i, where 1 <= f < 2. d2 is an approximation of f. */ - ds = (d2 - 1.5) * 0.289529654602168 + 0.1760912590558 + i * 0.301029995663981; - k = (int) ds; - if (ds < 0.0 && ds != k) k--; /* want k = floor(ds) */ - k_check = true; - if (k >= 0 && k <= Ten_pmax) { - if (d < tens[k]) k--; - k_check = false; - } - /* At this point floor(log10(d)) <= k <= floor(log10(d))+1. - If k_check is zero, we're guaranteed that k = floor(log10(d)). */ - j = bbits[0] - i - 1; - /* At this point d = b/2^j, where b is an odd integer. */ - if (j >= 0) { - b2 = 0; - s2 = j; - } else { - b2 = -j; - s2 = 0; - } - if (k >= 0) { - b5 = 0; - s5 = k; - s2 += k; - } else { - b2 -= k; - b5 = -k; - s5 = 0; - } - /* At this point d/10^k = (b * 2^b2 * 5^b5) / (2^s2 * 5^s5), where b is an odd integer, - b2 >= 0, b5 >= 0, s2 >= 0, and s5 >= 0. */ - if (mode < 0 || mode > 9) mode = 0; - try_quick = true; - if (mode > 5) { - mode -= 4; - try_quick = false; - } - leftright = true; - ilim = ilim1 = 0; - switch (mode) { - case 0: - case 1: - ilim = ilim1 = -1; - i = 18; - ndigits = 0; - break; - case 2: - leftright = false; - /* fall through */ - case 4: - if (ndigits <= 0) ndigits = 1; - ilim = ilim1 = i = ndigits; - break; - case 3: - leftright = false; - /* fall through */ - case 5: - i = ndigits + k + 1; - ilim = i; - ilim1 = i - 1; - if (i <= 0) i = 1; - } - /* ilim is the maximum number of significant digits we want, based on k and ndigits. */ - /* ilim1 is the maximum number of significant digits we want, based on k and ndigits, - when it turns out that k was computed too high by one. */ - - boolean fast_failed = false; - if (ilim >= 0 && ilim <= Quick_max && try_quick) { - - /* Try to get by with floating-point arithmetic. */ - - i = 0; - d2 = d; - k0 = k; - ilim0 = ilim; - ieps = 2; /* conservative */ - /* Divide d by 10^k, keeping track of the roundoff error and avoiding overflows. */ - if (k > 0) { - ds = tens[k & 0xf]; - j = k >> 4; - if ((j & Bletch) != 0) { - /* prevent overflows */ - j &= Bletch - 1; - d /= bigtens[n_bigtens - 1]; - ieps++; - } - for (; (j != 0); j >>= 1, i++) - if ((j & 1) != 0) { - ieps++; - ds *= bigtens[i]; - } - d /= ds; - } else if ((j1 = -k) != 0) { - d *= tens[j1 & 0xf]; - for (j = j1 >> 4; (j != 0); j >>= 1, i++) - if ((j & 1) != 0) { - ieps++; - d *= bigtens[i]; - } - } - /* Check that k was computed correctly. */ - if (k_check && d < 1.0 && ilim > 0) { - if (ilim1 <= 0) fast_failed = true; - else { - ilim = ilim1; - k--; - d *= 10.; - ieps++; - } - } - /* eps bounds the cumulative error. */ - // eps = ieps*d + 7.0; - // word0(eps) -= (P-1)*Exp_msk1; - eps = ieps * d + 7.0; - eps = setWord0(eps, word0(eps) - (P - 1) * Exp_msk1); - if (ilim == 0) { - S = mhi = null; - d -= 5.0; - if (d > eps) { - buf.append('1'); - k++; - return k + 1; - } - if (d < -eps) { - buf.setLength(0); - buf.append('0'); /* copy "0" to buffer */ - return 1; - } - fast_failed = true; - } - if (!fast_failed) { - fast_failed = true; - if (leftright) { - /* Use Steele & White method of only - * generating digits needed. - */ - eps = 0.5 / tens[ilim - 1] - eps; - for (i = 0; ; ) { - L = (long) d; - d -= L; - buf.append((char) ('0' + L)); - if (d < eps) { - return k + 1; - } - if (1.0 - d < eps) { - // goto bump_up; - char lastCh; - while (true) { - lastCh = buf.charAt(buf.length() - 1); - buf.setLength(buf.length() - 1); - if (lastCh != '9') break; - if (buf.length() == 0) { - k++; - lastCh = '0'; - break; - } - } - buf.append((char) (lastCh + 1)); - return k + 1; - } - if (++i >= ilim) break; - eps *= 10.0; - d *= 10.0; - } - } else { - /* Generate ilim digits, then fix them up. */ - eps *= tens[ilim - 1]; - for (i = 1; ; i++, d *= 10.0) { - L = (long) d; - d -= L; - buf.append((char) ('0' + L)); - if (i == ilim) { - if (d > 0.5 + eps) { - // goto bump_up; - char lastCh; - while (true) { - lastCh = buf.charAt(buf.length() - 1); - buf.setLength(buf.length() - 1); - if (lastCh != '9') break; - if (buf.length() == 0) { - k++; - lastCh = '0'; - break; - } - } - buf.append((char) (lastCh + 1)); - return k + 1; - } else if (d < 0.5 - eps) { - stripTrailingZeroes(buf); - // while(*--s == '0') ; - // s++; - return k + 1; - } - break; - } - } - } - } - if (fast_failed) { - buf.setLength(0); - d = d2; - k = k0; - ilim = ilim0; - } - } - - /* Do we have a "small" integer? */ - - if (be[0] >= 0 && k <= Int_max) { - /* Yes. */ - ds = tens[k]; - if (ndigits < 0 && ilim <= 0) { - S = mhi = null; - if (ilim < 0 || d < 5 * ds || (!biasUp && d == 5 * ds)) { - buf.setLength(0); - buf.append('0'); /* copy "0" to buffer */ - return 1; - } - buf.append('1'); - k++; - return k + 1; - } - for (i = 1; ; i++) { - L = (long) (d / ds); - d -= L * ds; - buf.append((char) ('0' + L)); - if (i == ilim) { - d += d; - if ((d > ds) || (d == ds && (((L & 1) != 0) || biasUp))) { - // bump_up: - // while(*--s == '9') - // if (s == buf) { - // k++; - // *s = '0'; - // break; - // } - // ++*s++; - char lastCh; - while (true) { - lastCh = buf.charAt(buf.length() - 1); - buf.setLength(buf.length() - 1); - if (lastCh != '9') break; - if (buf.length() == 0) { - k++; - lastCh = '0'; - break; - } - } - buf.append((char) (lastCh + 1)); - } - break; - } - d *= 10.0; - if (d == 0) break; - } - return k + 1; - } - - m2 = b2; - m5 = b5; - mhi = mlo = null; - if (leftright) { - if (mode < 2) { - i = (denorm) ? be[0] + (Bias + (P - 1) - 1 + 1) : 1 + P - bbits[0]; - /* i is 1 plus the number of trailing zero bits in d's significand. Thus, - (2^m2 * 5^m5) / (2^(s2+i) * 5^s5) = (1/2 lsb of d)/10^k. */ - } else { - j = ilim - 1; - if (m5 >= j) m5 -= j; - else { - s5 += j -= m5; - b5 += j; - m5 = 0; - } - if ((i = ilim) < 0) { - m2 -= i; - i = 0; - } - /* (2^m2 * 5^m5) / (2^(s2+i) * 5^s5) = (1/2 * 10^(1-ilim))/10^k. */ - } - b2 += i; - s2 += i; - mhi = BigInteger.valueOf(1); - /* (mhi * 2^m2 * 5^m5) / (2^s2 * 5^s5) = one-half of last printed (when mode >= 2) or - input (when mode < 2) significant digit, divided by 10^k. */ - } - /* We still have d/10^k = (b * 2^b2 * 5^b5) / (2^s2 * 5^s5). Reduce common factors in - b2, m2, and s2 without changing the equalities. */ - if (m2 > 0 && s2 > 0) { - i = (m2 < s2) ? m2 : s2; - b2 -= i; - m2 -= i; - s2 -= i; - } - - /* Fold b5 into b and m5 into mhi. */ - if (b5 > 0) { - if (leftright) { - if (m5 > 0) { - mhi = pow5mult(mhi, m5); - b1 = mhi.multiply(b); - b = b1; - } - if ((j = b5 - m5) != 0) b = pow5mult(b, j); - } else b = pow5mult(b, b5); - } - /* Now we have d/10^k = (b * 2^b2) / (2^s2 * 5^s5) and - (mhi * 2^m2) / (2^s2 * 5^s5) = one-half of last printed or input significant digit, divided by 10^k. */ - - S = BigInteger.valueOf(1); - if (s5 > 0) S = pow5mult(S, s5); - /* Now we have d/10^k = (b * 2^b2) / (S * 2^s2) and - (mhi * 2^m2) / (S * 2^s2) = one-half of last printed or input significant digit, divided by 10^k. */ - - /* Check for special case that d is a normalized power of 2. */ - spec_case = false; - if (mode < 2) { - if ((word1(d) == 0) - && ((word0(d) & Bndry_mask) == 0) - && ((word0(d) & (Exp_mask & Exp_mask << 1)) != 0)) { - /* The special case. Here we want to be within a quarter of the last input - significant digit instead of one half of it when the decimal output string's value is less than d. */ - b2 += Log2P; - s2 += Log2P; - spec_case = true; - } - } - - /* Arrange for convenient computation of quotients: - * shift left if necessary so divisor has 4 leading 0 bits. - * - * Perhaps we should just compute leading 28 bits of S once - * and for all and pass them and a shift to quorem, so it - * can do shifts and ors to compute the numerator for q. - */ - byte[] S_bytes = S.toByteArray(); - int S_hiWord = 0; - for (int idx = 0; idx < 4; idx++) { - S_hiWord = (S_hiWord << 8); - if (idx < S_bytes.length) S_hiWord |= (S_bytes[idx] & 0xFF); - } - if ((i = (((s5 != 0) ? 32 - hi0bits(S_hiWord) : 1) + s2) & 0x1f) != 0) i = 32 - i; - /* i is the number of leading zero bits in the most significant word of S*2^s2. */ - if (i > 4) { - i -= 4; - b2 += i; - m2 += i; - s2 += i; - } else if (i < 4) { - i += 28; - b2 += i; - m2 += i; - s2 += i; - } - /* Now S*2^s2 has exactly four leading zero bits in its most significant word. */ - if (b2 > 0) b = b.shiftLeft(b2); - if (s2 > 0) S = S.shiftLeft(s2); - /* Now we have d/10^k = b/S and - (mhi * 2^m2) / S = maximum acceptable error, divided by 10^k. */ - if (k_check) { - if (b.compareTo(S) < 0) { - k--; - b = b.multiply(BigInteger.valueOf(10)); /* we botched the k estimate */ - if (leftright) mhi = mhi.multiply(BigInteger.valueOf(10)); - ilim = ilim1; - } - } - /* At this point 1 <= d/10^k = b/S < 10. */ - - if (ilim <= 0 && mode > 2) { - /* We're doing fixed-mode output and d is less than the minimum nonzero output in this mode. - Output either zero or the minimum nonzero output depending on which is closer to d. */ - if ((ilim < 0) - || ((i = b.compareTo(S = S.multiply(BigInteger.valueOf(5)))) < 0) - || ((i == 0 && !biasUp))) { - /* Always emit at least one digit. If the number appears to be zero - using the current mode, then emit one '0' digit and set decpt to 1. */ - /*no_digits: - k = -1 - ndigits; - goto ret; */ - buf.setLength(0); - buf.append('0'); /* copy "0" to buffer */ - return 1; - // goto no_digits; - } - // one_digit: - buf.append('1'); - k++; - return k + 1; - } - if (leftright) { - if (m2 > 0) mhi = mhi.shiftLeft(m2); - - /* Compute mlo -- check for special case - * that d is a normalized power of 2. - */ - - mlo = mhi; - if (spec_case) { - mhi = mlo; - mhi = mhi.shiftLeft(Log2P); - } - /* mlo/S = maximum acceptable error, divided by 10^k, if the output is less than d. */ - /* mhi/S = maximum acceptable error, divided by 10^k, if the output is greater than d. */ - - for (i = 1; ; i++) { - BigInteger[] divResult = b.divideAndRemainder(S); - b = divResult[1]; - dig = (char) (divResult[0].intValue() + '0'); - /* Do we yet have the shortest decimal string - * that will round to d? - */ - j = b.compareTo(mlo); - /* j is b/S compared with mlo/S. */ - delta = S.subtract(mhi); - j1 = (delta.signum() <= 0) ? 1 : b.compareTo(delta); - /* j1 is b/S compared with 1 - mhi/S. */ - if ((j1 == 0) && (mode == 0) && ((word1(d) & 1) == 0)) { - if (dig == '9') { - buf.append('9'); - if (roundOff(buf)) { - k++; - buf.append('1'); - } - return k + 1; - // goto round_9_up; - } - if (j > 0) dig++; - buf.append(dig); - return k + 1; - } - if ((j < 0) || ((j == 0) && (mode == 0) && ((word1(d) & 1) == 0))) { - if (j1 > 0) { - /* Either dig or dig+1 would work here as the least significant decimal digit. - Use whichever would produce a decimal value closer to d. */ - b = b.shiftLeft(1); - j1 = b.compareTo(S); - if (((j1 > 0) || (j1 == 0 && (((dig & 1) == 1) || biasUp))) - && (dig++ == '9')) { - buf.append('9'); - if (roundOff(buf)) { - k++; - buf.append('1'); - } - return k + 1; - // goto round_9_up; - } - } - buf.append(dig); - return k + 1; - } - if (j1 > 0) { - if (dig == '9') { - /* possible if i == 1 */ - // round_9_up: - // *s++ = '9'; - // goto roundoff; - buf.append('9'); - if (roundOff(buf)) { - k++; - buf.append('1'); - } - return k + 1; - } - buf.append((char) (dig + 1)); - return k + 1; - } - buf.append(dig); - if (i == ilim) break; - b = b.multiply(BigInteger.valueOf(10)); - if (mlo == mhi) mlo = mhi = mhi.multiply(BigInteger.valueOf(10)); - else { - mlo = mlo.multiply(BigInteger.valueOf(10)); - mhi = mhi.multiply(BigInteger.valueOf(10)); - } - } - } else - for (i = 1; ; i++) { - // (char)(dig = quorem(b,S) + '0'); - BigInteger[] divResult = b.divideAndRemainder(S); - b = divResult[1]; - dig = (char) (divResult[0].intValue() + '0'); - buf.append(dig); - if (i >= ilim) break; - b = b.multiply(BigInteger.valueOf(10)); - } - - /* Round off last digit */ - - b = b.shiftLeft(1); - j = b.compareTo(S); - if ((j > 0) || (j == 0 && (((dig & 1) == 1) || biasUp))) { - // roundoff: - // while(*--s == '9') - // if (s == buf) { - // k++; - // *s++ = '1'; - // goto ret; - // } - // ++*s++; - if (roundOff(buf)) { - k++; - buf.append('1'); - return k + 1; - } - } else { - stripTrailingZeroes(buf); - // while(*--s == '0') ; - // s++; - } - // ret: - // Bfree(S); - // if (mhi) { - // if (mlo && mlo != mhi) - // Bfree(mlo); - // Bfree(mhi); - // } - // ret1: - // Bfree(b); - // JS_ASSERT(s < buf + bufsize); - return k + 1; - } - - private static void stripTrailingZeroes(StringBuilder buf) { - // while(*--s == '0') ; - // s++; - int bl = buf.length(); - while (bl-- > 0 && buf.charAt(bl) == '0') { - // empty - } - buf.setLength(bl + 1); - } - - /* Mapping of JSDToStrMode -> JS_dtoa mode */ - private static final int[] dtoaModes = { - 0, /* DTOSTR_STANDARD */ 0, /* DTOSTR_STANDARD_EXPONENTIAL, */ 3, /* DTOSTR_FIXED, */ - 2, /* DTOSTR_EXPONENTIAL, */ 2 - }; /* DTOSTR_PRECISION */ - - static void JS_dtostr(StringBuilder buffer, int mode, int precision, double d) { - int decPt; /* Position of decimal point relative to first digit returned by JS_dtoa */ - boolean[] sign = new boolean[1]; /* true if the sign bit was set in d */ - int nDigits; /* Number of significand digits returned by JS_dtoa */ - - // JS_ASSERT(bufferSize >= (size_t)(mode <= DTOSTR_STANDARD_EXPONENTIAL ? - // DTOSTR_STANDARD_BUFFER_SIZE : - // DTOSTR_VARIABLE_BUFFER_SIZE(precision))); - - if (mode == DTOSTR_FIXED && (d >= 1e21 || d <= -1e21)) - mode = - DTOSTR_STANDARD; /* Change mode here rather than below because the buffer may not be large enough to hold a large integer. */ - - decPt = JS_dtoa(d, dtoaModes[mode], mode >= DTOSTR_FIXED, precision, sign, buffer); - nDigits = buffer.length(); - - /* If Infinity, -Infinity, or NaN, return the string regardless of the mode. */ - if (decPt != 9999) { - boolean exponentialNotation = false; - int minNDigits = - 0; /* Minimum number of significand digits required by mode and precision */ - int p; - - switch (mode) { - case DTOSTR_STANDARD: - if (decPt < -5 || decPt > 21) exponentialNotation = true; - else minNDigits = decPt; - break; - - case DTOSTR_FIXED: - if (precision >= 0) minNDigits = decPt + precision; - else minNDigits = decPt; - break; - - case DTOSTR_EXPONENTIAL: - // JS_ASSERT(precision > 0); - minNDigits = precision; - /* fall through */ - case DTOSTR_STANDARD_EXPONENTIAL: - exponentialNotation = true; - break; - - case DTOSTR_PRECISION: - // JS_ASSERT(precision > 0); - minNDigits = precision; - if (decPt < -5 || decPt > precision) exponentialNotation = true; - break; - } - - /* If the number has fewer than minNDigits, pad it with zeros at the end */ - if (nDigits < minNDigits) { - p = minNDigits; - nDigits = minNDigits; - do { - buffer.append('0'); - } while (buffer.length() != p); - } - - if (exponentialNotation) { - /* Insert a decimal point if more than one significand digit */ - if (nDigits != 1) { - buffer.insert(1, '.'); - } - buffer.append('e'); - if ((decPt - 1) >= 0) buffer.append('+'); - buffer.append(decPt - 1); - // JS_snprintf(numEnd, bufferSize - (numEnd - buffer), "e%+d", - // decPt-1); - } else if (decPt != nDigits) { - /* Some kind of a fraction in fixed notation */ - // JS_ASSERT(decPt <= nDigits); - if (decPt > 0) { - /* dd...dd . dd...dd */ - buffer.insert(decPt, '.'); - } else { - /* 0 . 00...00dd...dd */ - for (int i = 0; i < 1 - decPt; i++) buffer.insert(0, '0'); - buffer.insert(1, '.'); - } - } - } - - /* If negative and neither -0.0 nor NaN, output a leading '-'. */ - if (sign[0] - && !(word0(d) == Sign_bit && word1(d) == 0) - && !((word0(d) & Exp_mask) == Exp_mask - && ((word1(d) != 0) || ((word0(d) & Frac_mask) != 0)))) { - buffer.insert(0, '-'); - } - } } diff -Nru rhino-1.7.15/src/org/mozilla/javascript/NativeNumber.java rhino-1.7.15.1/src/org/mozilla/javascript/NativeNumber.java --- rhino-1.7.15/src/org/mozilla/javascript/NativeNumber.java 2024-05-04 00:41:43.000000000 +0000 +++ rhino-1.7.15.1/src/org/mozilla/javascript/NativeNumber.java 2025-12-03 03:43:04.000000000 +0000 @@ -6,6 +6,8 @@ package org.mozilla.javascript; +import org.mozilla.javascript.dtoa.DecimalFormatter; + /** * This class implements the Number native object. * @@ -156,49 +158,13 @@ return ScriptRuntime.wrapNumber(value); case Id_toFixed: - int precisionMin = cx.version < Context.VERSION_ES6 ? -20 : 0; - return num_to(value, args, DToA.DTOSTR_FIXED, DToA.DTOSTR_FIXED, precisionMin, 0); + return js_toFixed(cx, value, args); case Id_toExponential: - { - // Handle special values before range check - if (Double.isNaN(value)) { - return "NaN"; - } - if (Double.isInfinite(value)) { - if (value >= 0) { - return "Infinity"; - } - return "-Infinity"; - } - // General case - return num_to( - value, - args, - DToA.DTOSTR_STANDARD_EXPONENTIAL, - DToA.DTOSTR_EXPONENTIAL, - 0, - 1); - } + return js_toExponential(value, args); case Id_toPrecision: - { - // Undefined precision, fall back to ToString() - if (args.length == 0 || Undefined.isUndefined(args[0])) { - return ScriptRuntime.numberToString(value, 10); - } - // Handle special values before range check - if (Double.isNaN(value)) { - return "NaN"; - } - if (Double.isInfinite(value)) { - if (value >= 0) { - return "Infinity"; - } - return "-Infinity"; - } - return num_to(value, args, DToA.DTOSTR_STANDARD, DToA.DTOSTR_PRECISION, 1, 0); - } + return js_toPrecision(value, args); default: throw new IllegalArgumentException(String.valueOf(id)); @@ -249,37 +215,75 @@ } } - @Override - public String toString() { - return ScriptRuntime.numberToString(doubleValue, 10); + private static Object js_toFixed(Context cx, double value, Object[] args) { + int fractionDigits; + if (args.length > 0 && !Undefined.isUndefined(args[0])) { + double p = ScriptRuntime.toInteger(args[0]); + int precisionMin = cx.version < Context.VERSION_ES6 ? -20 : 0; + /* We allow a larger range of precision than + ECMA requires; this is permitted by ECMA. */ + checkPrecision(p, precisionMin, args[0]); + fractionDigits = ScriptRuntime.toInt32(p); + } else { + fractionDigits = 0; + } + + if (!Double.isFinite(value)) { + return ScriptRuntime.toString(value); + } + return DecimalFormatter.toFixed(value, fractionDigits); } - private static String num_to( - double val, - Object[] args, - int zeroArgMode, - int oneArgMode, - int precisionMin, - int precisionOffset) { - int precision; - if (args.length == 0) { - precision = 0; - oneArgMode = zeroArgMode; + private static Object js_toExponential(double value, Object[] args) { + double p; + boolean wasUndefined; + if (args.length > 0 && !Undefined.isUndefined(args[0])) { + wasUndefined = false; + p = ScriptRuntime.toInteger(args[0]); } else { - /* We allow a larger range of precision than - ECMA requires; this is permitted by ECMA. */ - double p = ScriptRuntime.toInteger(args[0]); - if (p < precisionMin || p > MAX_PRECISION) { - String msg = - ScriptRuntime.getMessageById( - "msg.bad.precision", ScriptRuntime.toString(args[0])); - throw ScriptRuntime.rangeError(msg); - } - precision = ScriptRuntime.toInt32(p); + wasUndefined = true; + p = 0.0; } - StringBuilder sb = new StringBuilder(); - DToA.JS_dtostr(sb, oneArgMode, precision + precisionOffset, val); - return sb.toString(); + + if (!Double.isFinite(value)) { + return ScriptRuntime.toString(value); + } + checkPrecision(p, 0.0, args.length > 0 ? args[0] : Undefined.instance); + + // Trigger the special handling for undefined, which requires that + // we hold off on this bit until the checks above,. + int fractionDigits = wasUndefined ? -1 : ScriptRuntime.toInt32(p); + + return DecimalFormatter.toExponential(value, fractionDigits); + } + + private static Object js_toPrecision(double value, Object[] args) { + // Undefined precision, fall back to ToString() + if (args.length == 0 || Undefined.isUndefined(args[0])) { + return ScriptRuntime.toString(value); + } + + double p = ScriptRuntime.toInteger(args[0]); + if (!Double.isFinite(value)) { + return ScriptRuntime.toString(value); + } + checkPrecision(p, 1.0, args[0]); + int precision = ScriptRuntime.toInt32(p); + + return DecimalFormatter.toPrecision(value, precision); + } + + private static void checkPrecision(double p, double min, Object arg) { + if (p < min || p > MAX_PRECISION) { + String msg = + ScriptRuntime.getMessageById("msg.bad.precision", ScriptRuntime.toString(arg)); + throw ScriptRuntime.rangeError(msg); + } + } + + @Override + public String toString() { + return ScriptRuntime.numberToString(doubleValue, 10); } static Object isFinite(Object val) { @@ -309,7 +313,7 @@ } private static boolean isDoubleInteger(double d) { - return !Double.isInfinite(d) && !Double.isNaN(d) && (Math.floor(d) == d); + return Double.isFinite(d) && (Math.floor(d) == d); } private static boolean isSafeInteger(Number val) { diff -Nru rhino-1.7.15/src/org/mozilla/javascript/ScriptRuntime.java rhino-1.7.15.1/src/org/mozilla/javascript/ScriptRuntime.java --- rhino-1.7.15/src/org/mozilla/javascript/ScriptRuntime.java 2024-05-04 00:41:43.000000000 +0000 +++ rhino-1.7.15.1/src/org/mozilla/javascript/ScriptRuntime.java 2025-12-03 03:43:04.000000000 +0000 @@ -18,8 +18,8 @@ import java.util.ResourceBundle; import java.util.function.BiConsumer; import org.mozilla.javascript.ast.FunctionNode; +import org.mozilla.javascript.dtoa.DoubleFormatter; import org.mozilla.javascript.v8dtoa.DoubleConversion; -import org.mozilla.javascript.v8dtoa.FastDtoa; import org.mozilla.javascript.xml.XMLLib; import org.mozilla.javascript.xml.XMLObject; @@ -1061,27 +1061,20 @@ } public static String numberToString(double d, int base) { + if (base == 10) { + // Common case: DoubleFormatter efficiently identifies non-finite + // numbers. Do this before other checks. + return DoubleFormatter.toString(d); + } + if ((base < 2) || (base > 36)) { throw Context.reportRuntimeErrorById("msg.bad.radix", Integer.toString(base)); } - if (Double.isNaN(d)) return "NaN"; if (d == Double.POSITIVE_INFINITY) return "Infinity"; if (d == Double.NEGATIVE_INFINITY) return "-Infinity"; if (d == 0.0) return "0"; - - if (base != 10) { - return DToA.JS_dtobasestr(base, d); - } - // V8 FastDtoa can't convert all numbers, so try it first but - // fall back to old DToA in case it fails - String result = FastDtoa.numberToString(d); - if (result != null) { - return result; - } - StringBuilder buffer = new StringBuilder(); - DToA.JS_dtostr(buffer, DToA.DTOSTR_STANDARD, 0, d); - return buffer.toString(); + return DToA.JS_dtobasestr(base, d); } public static String bigIntToString(BigInteger n, int base) { diff -Nru rhino-1.7.15/src/org/mozilla/javascript/dtoa/Decimal.java rhino-1.7.15.1/src/org/mozilla/javascript/dtoa/Decimal.java --- rhino-1.7.15/src/org/mozilla/javascript/dtoa/Decimal.java 1970-01-01 00:00:00.000000000 +0000 +++ rhino-1.7.15.1/src/org/mozilla/javascript/dtoa/Decimal.java 2025-12-03 03:43:04.000000000 +0000 @@ -0,0 +1,306 @@ +package org.mozilla.javascript.dtoa; + +/** + * This class formats a decimal number into a string representation and stores the result in a + * buffer. It is highly optimized for the case of formatting a double and only works if the number + * has a maximum of 17 digits of precision. + * + *

Based on code by Guilietti: + * https://github.com/c4f7fcce9cb06515/Schubfach/blob/3c92d3c9b1fead540616c918cdfef432bca53dfa/todec/src/math/FloatToDecimal.java + */ +public class Decimal { + // Used for left-to-right digit extraction. + private static final int MASK_28 = (1 << 28) - 1; + + /* + Room for the longer of the forms. + Always 17 significant digits. + -ddddd.dddddddddddd H + 2 characters + -0.000000ddddddddddddddddd H + 9 characters + (JS will used fixed format down to -6 exponent) + -d.ddddddddddddddddE-eee H + 7 characters + -ddddddddddddddddd0000 H + 5 characters + (JS will use fixed format up to 21 exponent) + where there are H digits d + + That means we need 26 characters for the largest possible number. + We will use 32 because powers of two are good. + */ + public static final int MAX_CHARS = 32; + + private final long digits; + private final int exponent; + private final boolean negative; + private int length; + private final char[] buf = new char[MAX_CHARS]; + + enum Mode { + DEFAULT, + TO_EXPONENTIAL + }; + + Decimal(long d, int e, boolean n) { + this.digits = d; + this.exponent = e; + this.negative = n; + } + + /** + * Format the number according to the formatting rules in EcmaScript chapter 6, as defined for + * the "Number::toString" operation, for radix 10. + */ + @Override + public String toString() { + return toString(Mode.DEFAULT); + } + + String toString(Mode mode) { + length = 0; + + /* + For details not discussed here see section 10 of [1]. + + Determine len such that + 10^(len-1) <= f < 10^len + */ + int len = MathUtils.flog10pow2(Long.SIZE - Long.numberOfLeadingZeros(digits)); + if (digits >= MathUtils.pow10(len)) { + len += 1; + } + + /* + Let fp and ep be the original f and e, respectively. + Transform f and e to ensure + 10^(H-1) <= f < 10^H + fp 10^ep = f 10^(e-H) = 0.f 10^e + */ + long f = digits * MathUtils.pow10(DoubleFormatter.H - len); + int e = exponent + len; + /* + The toChars?() methods perform left-to-right digits extraction + using ints, provided that the arguments are limited to 8 digits. + Therefore, split the H = 17 digits of f into: + h = the most significant digit of f + m = the next 8 most significant digits of f + l = the last 8, least significant digits of f + + For n = 17, m = 8 the table in section 10 of [1] shows + floor(f / 10^8) = floor(193_428_131_138_340_668 f / 2^84) = + floor(floor(193_428_131_138_340_668 f / 2^64) / 2^20) + and for n = 9, m = 8 + floor(hm / 10^8) = floor(1_441_151_881 hm / 2^57) + */ + + /* + * Implementation note: The calculations above adjusts "f" so that + * the most significant bits are at the front, with trailing zeroes. + * That lets the bit of code below separate the digits into three + * parts -- the first digit, the next 8, and the 8 after that. + * We can then stringify it much more efficiently using this here clever + * algorithm by Giulietti. We have adapted his original code a bit + * to handle JavaScript, which requires fixed-format numbers for a + * wider range of values before switching to exponential format. + */ + long hm = MathUtils.multiplyHigh(f, 193_428_131_138_340_668L) >>> 20; + int l = (int) (f - 100_000_000L * hm); + int h = (int) ((hm * 1_441_151_881L) >>> 57); + int m = (int) (hm - 100_000_000L * h); + + if (negative) { + append('-'); + } + + if (mode == Mode.DEFAULT) { + if (0 < e && e <= 8) { + return toFixed(h, m, l, e); + } + if (8 < e && e <= 16) { + return toFixedBigger(h, m, l, e); + } + if (16 < e && e <= 21) { + return toFixedBiggest(h, m, l, e); + } + if (-6 < e && e <= 0) { + return toFixedSmall(h, m, l, e); + } + } + return toExponential(h, m, l, e); + } + + private String toFixed(int h, int m, int l, int e) { + assert e <= 8; + /* + 0 < e <= 8: plain format without leading zeroes. + Left-to-right digits extraction: + algorithm 1 in [3], with b = 10, k = 8, n = 28. + */ + appendDigit(h); + int y = y(m); + int t; + int i = 1; + for (; i < e; ++i) { + t = 10 * y; + appendDigit(t >>> 28); + y = t & MASK_28; + } + append('.'); + for (; i <= 8; ++i) { + t = 10 * y; + appendDigit(t >>> 28); + y = t & MASK_28; + } + lowDigits(l); + return makeString(); + } + + private String toFixedBigger(int h, int m, int l, int e) { + assert e > 8 && e <= 16; + /* + 8 > e <= 16: plain format without leading zeroes. + Left-to-right digits extraction: + But the first 9 characters are before the decimal. + */ + appendDigit(h); + append8Digits(m); + int y = y(l); + int t; + int i = 9; + for (; i < e; ++i) { + t = 10 * y; + appendDigit(t >>> 28); + y = t & MASK_28; + } + append('.'); + for (; i <= 16; ++i) { + t = 10 * y; + appendDigit(t >>> 28); + y = t & MASK_28; + } + trimZeroes(); + return makeString(); + } + + private String toFixedBiggest(int h, int m, int l, int e) { + assert e > 16; + /* + 16 < e: plain format with trailing zeroes. + */ + appendDigit(h); + append8Digits(m); + append8Digits(l); + for (int i = 17; i < e; i++) { + append('0'); + } + return makeString(); + } + + private String toFixedSmall(int h, int m, int l, int e) { + assert e <= 0; + // -3 < e <= 0: plain format with leading zeroes. + appendDigit(0); + append('.'); + for (; e < 0; ++e) { + appendDigit(0); + } + appendDigit(h); + append8Digits(m); + lowDigits(l); + return makeString(); + } + + private String toExponential(int h, int m, int l, int e) { + // -3 >= e | e > 7: computerized scientific notation + appendDigit(h); + append('.'); + append8Digits(m); + lowDigits(l); + exponent(e - 1); + return makeString(); + } + + private int y(int a) { + /* + Algorithm 1 in [3] needs computation of + floor((a + 1) 2^n / b^k) - 1 + with a < 10^8, b = 10, k = 8, n = 28. + Noting that + (a + 1) 2^n <= 10^8 2^28 < 10^17 + For n = 17, m = 8 the table in section 10 of [1] leads to: + */ + return (int) (MathUtils.multiplyHigh((long) (a + 1) << 28, 193_428_131_138_340_668L) >>> 20) + - 1; + } + + private void lowDigits(int l) { + if (l != 0) { + append8Digits(l); + } + trimZeroes(); + } + + private void append8Digits(int m) { + /* + Left-to-right digits extraction: + algorithm 1 in [3], with b = 10, k = 8, n = 28. + */ + int y = y(m); + for (int i = 0; i < 8; ++i) { + int t = 10 * y; + appendDigit(t >>> 28); + y = t & MASK_28; + } + } + + private void exponent(int e) { + assert e >= -999 && e <= 999; + append('e'); + if (e < 0) { + append('-'); + e = -e; + } else { + append('+'); + } + if (e < 10) { + appendDigit(e); + return; + } + int d; + if (e >= 100) { + /* + For n = 3, m = 2 the table in section 10 of [1] shows + floor(e / 100) = floor(1_311 e / 2^17) + */ + d = (e * 1_311) >>> 17; + appendDigit(d); + e -= 100 * d; + } + /* + For n = 2, m = 1 the table in section 10 of [1] shows + floor(e / 10) = floor(103 e / 2^10) + */ + d = (e * 103) >>> 10; + appendDigit(d); + appendDigit(e - 10 * d); + } + + private void trimZeroes() { + while (length > 0 && buf[length - 1] == '0') { + length--; + } + if (length > 0 && buf[length - 1] == '.') { + length--; + } + } + + private void append(char ch) { + buf[length++] = ch; + } + + private void appendDigit(int d) { + buf[length++] = (char) ('0' + d); + } + + private String makeString() { + return new String(buf, 0, length); + } +} diff -Nru rhino-1.7.15/src/org/mozilla/javascript/dtoa/DecimalFormatter.java rhino-1.7.15.1/src/org/mozilla/javascript/dtoa/DecimalFormatter.java --- rhino-1.7.15/src/org/mozilla/javascript/dtoa/DecimalFormatter.java 1970-01-01 00:00:00.000000000 +0000 +++ rhino-1.7.15.1/src/org/mozilla/javascript/dtoa/DecimalFormatter.java 2025-12-03 03:43:04.000000000 +0000 @@ -0,0 +1,163 @@ +package org.mozilla.javascript.dtoa; + +import java.math.BigDecimal; +import java.math.MathContext; +import java.math.RoundingMode; + +public class DecimalFormatter { + private static final double MAX_FIXED = 1E21; + + /** + * The algorithm of Number.prototype.toExponential. If fractionDigits is < 0, then it indicates + * the special case that the value was previously undefined, which calls for a different + * precision for the calculation. + */ + public static String toExponential(double v, int fractionDigits) { + assert Double.isFinite(v); + + if (fractionDigits < 0) { + // In this case, we are supposed to use the "shortest possible representation." + // This is what our usual toString implementation does + return DoubleFormatter.toDecimal(v).toString(Decimal.Mode.TO_EXPONENTIAL); + } + + boolean negative = Math.signum(v) < 0; + double val = v; + if (negative) { + val = Math.abs(v); + } + BigDecimal bd = + new BigDecimal(val, new MathContext(fractionDigits + 1, RoundingMode.HALF_UP)); + + int exponent; + if (bd.scale() >= 0) { + exponent = bd.precision() - bd.scale() - 1; + } else { + // digits000 + exponent = bd.precision() + -bd.scale() - 1; + } + + return toExponentialString(bd, exponent, fractionDigits, negative); + } + + /** The algorithm of Number.prototype.toFixed(fractionDigits). */ + public static String toFixed(double v, int fractionDigits) { + assert Double.isFinite(v); + assert fractionDigits >= 0; + boolean negative = Math.signum(v) < 0; + double val = v; + if (negative) { + val = Math.abs(v); + } + if (val >= MAX_FIXED) { + return DoubleFormatter.toString(v); + } + BigDecimal bd = new BigDecimal(val, MathContext.UNLIMITED); + if (bd.scale() > fractionDigits) { + bd = bd.setScale(fractionDigits, RoundingMode.HALF_UP); + } + return toFixedString(bd, fractionDigits, negative); + } + + /** The algorithm of Number.prototype.toPrecision() */ + public static String toPrecision(double v, int precision) { + assert Double.isFinite(v); + assert precision >= 1; + boolean negative = Math.signum(v) < 0; + double val; + if (negative) { + val = -v; + } else { + val = v; + } + BigDecimal bd = new BigDecimal(val, new MathContext(precision, RoundingMode.HALF_UP)); + + int scale = bd.scale(); + int numDigits = bd.precision(); + int exponent; + int fractionDigits; + if (scale >= 0) { + if (scale >= numDigits) { + // 0.digits000 + fractionDigits = precision; + } else { + // dig.its + fractionDigits = precision - (numDigits - scale); + } + exponent = numDigits - scale - 1; + } else { + // digits000 + fractionDigits = 0; + exponent = numDigits + -scale - 1; + } + + if (exponent < -6 || exponent >= precision) { + return toExponentialString(bd, exponent, precision - 1, negative); + } + return toFixedString(bd, fractionDigits, negative); + } + + private static String toFixedString(BigDecimal d, int fractionDigits, boolean negative) { + int scale = d.scale(); + // Turns out that, in UNLIMITED scale mode, BigDecimal will not + // produce a negative scale. + assert (scale >= 0); + String digits = d.unscaledValue().toString(); + int numDigits = digits.length(); + if (scale == 0 && fractionDigits == 0) { + if (negative) { + return "-" + digits; + } + return digits; + } + + // Room for digits, -, ., extra 0 + StringBuilder b = new StringBuilder(numDigits * 2 + 3); + if (negative) { + b.append('-'); + } + if (scale >= numDigits) { + // 0.000digits000 + b.append("0."); + fillZeroes(b, scale - numDigits); + b.append(digits); + } else { + // dig.its000 + b.append(digits.substring(0, numDigits - scale)); + b.append('.'); + b.append(digits.substring(numDigits - scale)); + } + fillZeroes(b, fractionDigits - scale); + return b.toString(); + } + + private static String toExponentialString( + BigDecimal d, int exponent, int fractionDigits, boolean negative) { + String digits = d.unscaledValue().toString(); + int numDigits = digits.length(); + // Room for digits, ., -, e+000 + StringBuilder b = new StringBuilder(numDigits + fractionDigits + 7); + + if (negative) { + b.append('-'); + } + b.append(digits.charAt(0)); + if (numDigits > 1 || fractionDigits >= 1) { + b.append('.'); + b.append(digits.substring(1)); + fillZeroes(b, fractionDigits - (numDigits - 1)); + } + b.append('e'); + if (exponent >= 0) { + b.append('+'); + } + b.append(exponent); + return b.toString(); + } + + private static void fillZeroes(StringBuilder b, int count) { + for (int i = 0; i < count; i++) { + b.append('0'); + } + } +} diff -Nru rhino-1.7.15/src/org/mozilla/javascript/dtoa/DoubleFormatter.java rhino-1.7.15.1/src/org/mozilla/javascript/dtoa/DoubleFormatter.java --- rhino-1.7.15/src/org/mozilla/javascript/dtoa/DoubleFormatter.java 1970-01-01 00:00:00.000000000 +0000 +++ rhino-1.7.15.1/src/org/mozilla/javascript/dtoa/DoubleFormatter.java 2025-12-03 03:43:04.000000000 +0000 @@ -0,0 +1,253 @@ +package org.mozilla.javascript.dtoa; + +/** + * This class formats a double into a set of digits and an exponent for further formatting by the + * Double class. It is based on the same code used by Jackson and in OpenJDK with the following + * copyright: + * + *

Copyright 2018-2020 Raffaello Giulietti + * + *

Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + *

The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + *

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +public class DoubleFormatter { + /* + For full details about this code see the following references: + + [1] Giulietti, "The Schubfach way to render doubles", + https://drive.google.com/open?id=1luHhyQF9zKlM8yJ1nebU0OgVYhfC6CBN + + [2] IEEE Computer Society, "IEEE Standard for Floating-Point Arithmetic" + + [3] Bouvier & Zimmermann, "Division-Free Binary-to-Decimal Conversion" + + Divisions are avoided altogether for the benefit of those architectures + that do not provide specific machine instructions or where they are slow. + This is discussed in section 10 of [1]. + */ + + // Sources with the license are here: + // https://github.com/c4f7fcce9cb06515/Schubfach/blob/3c92d3c9b1fead540616c918cdfef432bca53dfa/todec/src/math/FloatToDecimal.java + + // The precision in bits. + static final int P = 53; + + // Exponent width in bits. + private static final int W = (Double.SIZE - 1) - (P - 1); + + // Minimum value of the exponent: -(2^(W-1)) - P + 3. + static final int Q_MIN = (-1 << (W - 1)) - P + 3; + + // Maximum value of the exponent: 2^(W-1) - P. + static final int Q_MAX = (1 << (W - 1)) - P; + + // 10^(E_MIN - 1) <= MIN_VALUE < 10^E_MIN + static final int E_MIN = -323; + + // 10^(E_MAX - 1) <= MAX_VALUE < 10^E_MAX + static final int E_MAX = 309; + + // Threshold to detect tiny values, as in section 8.1.1 of [1] + static final long C_TINY = 3; + + // H is as in section 8 of [1]. + static final int H = 17; + + // Minimum value of the significand of a normal value: 2^(P-1). + private static final long C_MIN = 1L << (P - 1); + + // Mask to extract the biased exponent. + private static final int BQ_MASK = (1 << W) - 1; + + // Mask to extract the fraction bits. + private static final long T_MASK = (1L << (P - 1)) - 1; + + // Used in rop(). + private static final long MASK_63 = (1L << 63) - 1; + + /** + * Convert a double to String as defined in the "Number::toString" operation in ECMAScript. It + * can handle any number including non-finite numbers. + */ + public static String toString(double v) { + long bits = Double.doubleToRawLongBits(v); + long t = bits & T_MASK; + int bq = (int) (bits >>> (P - 1)) & BQ_MASK; + if (bq < BQ_MASK) { + if (bq == 0 && t == 0) { + return "0"; + } + return toDecimalImpl(bits, t, bq).toString(); + } + if (t != 0) { + return "NaN"; + } + return bits > 0 ? "Infinity" : "-Infinity"; + } + + /** + * Convert a double to a Decimal object that may be output in various ways. Unlike toString, and + * since it always returns a Decimal, it must be used with finite numbers only or the result is + * undetermined. + */ + public static Decimal toDecimal(double v) { + assert Double.isFinite(v); + long bits = Double.doubleToRawLongBits(v); + long t = bits & T_MASK; + int bq = (int) (bits >>> (P - 1)) & BQ_MASK; + return toDecimalImpl(bits, t, bq); + } + + private static Decimal toDecimalImpl(long bits, long t, int bq) { + /* + For full details see references [2] and [1]. + + For finite v != 0, determine integers c and q such that + |v| = c 2^q and + Q_MIN <= q <= Q_MAX and + either 2^(P-1) <= c < 2^P (normal) + or 0 < c < 2^(P-1) and q = Q_MIN (subnormal) + */ + // Only finite numbers are supported + assert bq < BQ_MASK; + boolean negative = false; + if (bits < 0) { + negative = true; + } + if (bq != 0) { + // normal value. Here mq = -q + int mq = -Q_MIN + 1 - bq; + long c = C_MIN | t; + // The fast path discussed in section 8.2 of [1]. + if (0 < mq && mq < P) { + long f = c >> mq; + if (f << mq == c) { + return new Decimal(f, 0, negative); + } + } + return toDecimalFull(-mq, c, 0, negative); + } + if (t != 0) { + // subnormal value + return t < C_TINY + ? toDecimalFull(Q_MIN, 10 * t, -1, negative) + : toDecimalFull(Q_MIN, t, 0, negative); + } + return new Decimal(0, 1, false); + } + + private static Decimal toDecimalFull(int q, long c, int dk, boolean negative) { + /* + The skeleton corresponds to figure 4 of [1]. + The efficient computations are those summarized in figure 7. + + Here's a correspondence between Java names and names in [1], + expressed as approximate LaTeX source code and informally. + Other names are identical. + cb: \bar{c} "c-bar" + cbr: \bar{c}_r "c-bar-r" + cbl: \bar{c}_l "c-bar-l" + + vb: \bar{v} "v-bar" + vbr: \bar{v}_r "v-bar-r" + vbl: \bar{v}_l "v-bar-l" + + rop: r_o' "r-o-prime" + */ + int out = (int) c & 0x1; + long cb = c << 2; + long cbr = cb + 2; + long cbl; + int k; + /* + flog10pow2(e) = floor(log_10(2^e)) + flog10threeQuartersPow2(e) = floor(log_10(3/4 2^e)) + flog2pow10(e) = floor(log_2(10^e)) + */ + if (c != C_MIN || q == Q_MIN) { + // regular spacing + cbl = cb - 2; + k = MathUtils.flog10pow2(q); + } else { + // irregular spacing + cbl = cb - 1; + k = MathUtils.flog10threeQuartersPow2(q); + } + int h = q + MathUtils.flog2pow10(-k) + 2; + + // g1 and g0 are as in section 9.9.3 of [1], so g = g1 2^63 + g0 + long g1 = MathUtils.g1(k); + long g0 = MathUtils.g0(k); + + long vb = rop(g1, g0, cb << h); + long vbl = rop(g1, g0, cbl << h); + long vbr = rop(g1, g0, cbr << h); + + long s = vb >> 2; + if (s >= 100) { + /* + For n = 17, m = 1 the table in section 10 of [1] shows + s' = floor(s / 10) = floor(s 115_292_150_460_684_698 / 2^60) + = floor(s 115_292_150_460_684_698 2^4 / 2^64) + + sp10 = 10 s' + tp10 = 10 t' + upin iff u' = sp10 10^k in Rv + wpin iff w' = tp10 10^k in Rv + See section 9.4 of [1]. + */ + long sp10 = 10 * MathUtils.multiplyHigh(s, 115_292_150_460_684_698L << 4); + long tp10 = sp10 + 10; + boolean upin = vbl + out <= sp10 << 2; + boolean wpin = (tp10 << 2) + out <= vbr; + if (upin != wpin) { + return new Decimal(upin ? sp10 : tp10, k, negative); + } + } + + /* + 10 <= s < 100 or s >= 100 and u', w' not in Rv + uin iff u = s 10^k in Rv + win iff w = t 10^k in Rv + See section 9.4 of [1]. + */ + long t = s + 1; + boolean uin = vbl + out <= s << 2; + boolean win = (t << 2) + out <= vbr; + if (uin != win) { + // Exactly one of u or w lies in Rv. + return new Decimal(uin ? s : t, k + dk, negative); + } + /* + Both u and w lie in Rv: determine the one closest to v. + See section 9.4 of [1]. + */ + long cmp = vb - ((s + t) << 1); + return new Decimal(cmp < 0 || (cmp == 0 && (s & 0x1) == 0) ? s : t, k + dk, negative); + } + + /* + Computes rop(cp g 2^(-127)), where g = g1 2^63 + g0 + See section 9.10 and figure 5 of [1]. + */ + private static long rop(long g1, long g0, long cp) { + long x1 = MathUtils.multiplyHigh(g0, cp); + long y0 = g1 * cp; + long y1 = MathUtils.multiplyHigh(g1, cp); + long z = (y0 >>> 1) + x1; + long vbp = y1 + (z >>> 63); + return vbp | ((z & MASK_63) + MASK_63) >>> 63; + } +} diff -Nru rhino-1.7.15/src/org/mozilla/javascript/dtoa/MathUtils.java rhino-1.7.15.1/src/org/mozilla/javascript/dtoa/MathUtils.java --- rhino-1.7.15/src/org/mozilla/javascript/dtoa/MathUtils.java 1970-01-01 00:00:00.000000000 +0000 +++ rhino-1.7.15.1/src/org/mozilla/javascript/dtoa/MathUtils.java 2025-12-03 03:43:04.000000000 +0000 @@ -0,0 +1,804 @@ +/* + * Copyright 2018-2020 Raffaello Giulietti + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package org.mozilla.javascript.dtoa; + +/** + * This class exposes package private utilities for other classes. Thus, all methods are assumed to + * be invoked with correct arguments, so these are not checked at all. + * + * @author Raffaello Giulietti + */ +final class MathUtils { + /* + For full details about this code see the following reference: + + Giulietti, "The Schubfach way to render doubles", + https://drive.google.com/open?id=1luHhyQF9zKlM8yJ1nebU0OgVYhfC6CBN + */ + + /* + The boundaries for k in g0(int) and g1(int). + K_MIN must be DoubleToDecimal.K_MIN or less. + K_MAX must be DoubleToDecimal.K_MAX or more. + */ + static final int K_MIN = -324; + static final int K_MAX = 292; + + // Must be DoubleToDecimal.H or more + static final int H = 17; + + // C_10 = floor(log10(2) * 2^Q_10), A_10 = floor(log10(3/4) * 2^Q_10) + private static final int Q_10 = 41; + private static final long C_10 = 661_971_961_083L; + private static final long A_10 = -274_743_187_321L; + + // C_2 = floor(log2(10) * 2^Q_2) + private static final int Q_2 = 38; + private static final long C_2 = 913_124_641_741L; + + private MathUtils() {} + + // The first powers of 10. The last entry must be 10^H. + private static final long[] pow10 = { + 1L, + 10L, + 100L, + 1_000L, + 10_000L, + 100_000L, + 1_000_000L, + 10_000_000L, + 100_000_000L, + 1_000_000_000L, + 10_000_000_000L, + 100_000_000_000L, + 1_000_000_000_000L, + 10_000_000_000_000L, + 100_000_000_000_000L, + 1_000_000_000_000_000L, + 10_000_000_000_000_000L, + 100_000_000_000_000_000L, + }; + + /** + * Returns 10{@code e}. + * + * @param e The exponent which must meet 0 ≤ {@code e} ≤ {@link #H}. + * @return 10{@code e}. + */ + static long pow10(int e) { + return pow10[e]; + } + + /** + * Returns the unique integer k such that 10k ≤ 2{@code + * e} < 10k+1. + * + *

The result is correct when |{@code e}| ≤ 5_456_721. Otherwise the result is undefined. + * + * @param e The exponent of 2, which should meet |{@code e}| ≤ 5_456_721 for safe results. + * @return ⌊log102{@code e}⌋. + */ + static int flog10pow2(int e) { + return (int) ((e * C_10) >> Q_10); + } + + /** + * Returns the unique integer k such that 10k ≤ 3/4 · + * 2{@code e} < 10k+1. + * + *

The result is correct when -2_956_395 ≤ {@code e} ≤ 2_500_325. Otherwise the result + * is undefined. + * + * @param e The exponent of 2, which should meet -2_956_395 ≤ {@code e} ≤ 2_500_325 for + * safe results. + * @return ⌊log10(3/4 · 2{@code e})⌋. + */ + static int flog10threeQuartersPow2(int e) { + return (int) ((e * C_10 + A_10) >> Q_10); + } + + /** + * Returns the unique integer k such that 2k ≤ 10{@code + * e} < 2k+1. + * + *

The result is correct when |{@code e}| ≤ 1_838_394. Otherwise the result is undefined. + * + * @param e The exponent of 10, which should meet |{@code e}| ≤ 1_838_394 for safe results. + * @return ⌊log210{@code e}⌋. + */ + static int flog2pow10(int e) { + return (int) ((e * C_2) >> Q_2); + } + + /** + * Let 10-{@code k} = β 2r, for the unique pair of + * integer r and real β meeting 2125β < + * 2126. Further, let g = ⌊β⌋ + 1. Split g + * into the higher 63 bits g1 and the lower 63 bits g0. + * Thus, g1 = ⌊g 2-63⌋ and + * g0 = g - g1 263. + * + *

This method returns g1 while {@link #g0(int)} returns + * g0. + * + *

If needed, the exponent r can be computed as r = {@code flog2pow10(-k)} - + * 125 (see {@link #flog2pow10(int)}). + * + * @param k The exponent of 10, which must meet {@link #K_MIN} ≤ {@code e} ≤ {@link + * #K_MAX}. + * @return g1 as described above. + */ + static long g1(int k) { + return g[(k - K_MIN) << 1]; + } + + /** + * Returns g0 as described in {@link #g1(int)}. + * + * @param k The exponent of 10, which must meet {@link #K_MIN} ≤ {@code e} ≤ {@link + * #K_MAX}. + * @return g0 as described in {@link #g1(int)}. + */ + static long g0(int k) { + return g[(k - K_MIN) << 1 | 1]; + } + + // a Java port of + // https://github.com/plokhotnyuk/jsoniter-scala/blob/c70a293ac802dc2eb44165471d76d7df2d4657b6/jsoniter-scala-core/native/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonWriter.scala#L2027 + static long multiplyHigh(long x, long y) { + // Karatsuba technique for two positive ints + long x2 = x & 0xFFFFFFFFL; + long y2 = y & 0xFFFFFFFFL; + long b = x2 * y2; + long x1 = x >>> 32; + long y1 = y >>> 32; + long a = x1 * y1; + return (((b >>> 32) + (x1 + x2) * (y1 + y2) - b - a) >>> 32) + a; + } + + /* + The precomputed values for g1(int) and g0(int). + The first entry must be for an exponent of K_MIN or less. + The last entry must be for an exponent of K_MAX or more. + */ + private static final long[] g = { + /* -324 */ 0x4F0C_EDC9_5A71_8DD4L, 0x5B01_E8B0_9AA0_D1B5L, + /* -323 */ 0x7E7B_160E_F71C_1621L, 0x119C_A780_F767_B5EEL, + /* -322 */ 0x652F_44D8_C5B0_11B4L, 0x0E16_EC67_2C52_F7F2L, + /* -321 */ 0x50F2_9D7A_37C0_0E29L, 0x5812_56B8_F042_5FF5L, + /* -320 */ 0x40C2_1794_F966_71BAL, 0x79A8_4560_C035_1991L, + /* -319 */ 0x679C_F287_F570_B5F7L, 0x75DA_089A_CD21_C281L, + /* -318 */ 0x52E3_F539_9126_F7F9L, 0x44AE_6D48_A41B_0201L, + /* -317 */ 0x424F_F761_40EB_F994L, 0x36F1_F106_E9AF_34CDL, + /* -316 */ 0x6A19_8BCE_CE46_5C20L, 0x57E9_81A4_A918_547BL, + /* -315 */ 0x54E1_3CA5_71D1_E34DL, 0x2CBA_CE1D_5413_76C9L, + /* -314 */ 0x43E7_63B7_8E41_82A4L, 0x23C8_A4E4_4342_C56EL, + /* -313 */ 0x6CA5_6C58_E39C_043AL, 0x060D_D4A0_6B9E_08B0L, + /* -312 */ 0x56EA_BD13_E949_9CFBL, 0x1E71_76E6_BC7E_6D59L, + /* -311 */ 0x4588_9743_2107_B0C8L, 0x7EC1_2BEB_C9FE_BDE1L, + /* -310 */ 0x6F40_F205_01A5_E7A7L, 0x7E01_DFDF_A997_9635L, + /* -309 */ 0x5900_C19D_9AEB_1FB9L, 0x4B34_B319_5479_44F7L, + /* -308 */ 0x4733_CE17_AF22_7FC7L, 0x55C3_C27A_A9FA_9D93L, + /* -307 */ 0x71EC_7CF2_B1D0_CC72L, 0x5606_03F7_765D_C8EAL, + /* -306 */ 0x5B23_9728_8E40_A38EL, 0x7804_CFF9_2B7E_3A55L, + /* -305 */ 0x48E9_45BA_0B66_E93FL, 0x1337_0CC7_55FE_9511L, + /* -304 */ 0x74A8_6F90_123E_41FEL, 0x51F1_AE0B_BCCA_881BL, + /* -303 */ 0x5D53_8C73_41CB_67FEL, 0x74C1_5809_63D5_39AFL, + /* -302 */ 0x4AA9_3D29_016F_8665L, 0x43CD_E007_8310_FAF3L, + /* -301 */ 0x7775_2EA8_024C_0A3CL, 0x0616_333F_381B_2B1EL, + /* -300 */ 0x5F90_F220_01D6_6E96L, 0x3811_C298_F9AF_55B1L, + /* -299 */ 0x4C73_F4E6_67DE_BEDEL, 0x600E_3547_2E25_DE28L, + /* -298 */ 0x7A53_2170_A631_3164L, 0x3349_EED8_49D6_303FL, + /* -297 */ 0x61DC_1AC0_84F4_2783L, 0x42A1_8BE0_3B11_C033L, + /* -296 */ 0x4E49_AF00_6A5C_EC69L, 0x1BB4_6FE6_95A7_CCF5L, + /* -295 */ 0x7D42_B19A_43C7_E0A8L, 0x2C53_E63D_BC3F_AE55L, + /* -294 */ 0x6435_5AE1_CFD3_1A20L, 0x2376_51CA_FCFF_BEAAL, + /* -293 */ 0x502A_AF1B_0CA8_E1B3L, 0x35F8_416F_30CC_9888L, + /* -292 */ 0x4022_25AF_3D53_E7C2L, 0x5E60_3458_F3D6_E06DL, + /* -291 */ 0x669D_0918_621F_D937L, 0x4A33_86F4_B957_CD7BL, + /* -290 */ 0x5217_3A79_E819_7A92L, 0x6E8F_9F2A_2DDF_D796L, + /* -289 */ 0x41AC_2EC7_ECE1_2EDBL, 0x720C_7F54_F17F_DFABL, + /* -288 */ 0x6913_7E0C_AE35_17C6L, 0x1CE0_CBBB_1BFF_CC45L, + /* -287 */ 0x540F_980A_24F7_4638L, 0x171A_3C95_AFFF_D69EL, + /* -286 */ 0x433F_ACD4_EA5F_6B60L, 0x127B_63AA_F333_1218L, + /* -285 */ 0x6B99_1487_DD65_7899L, 0x6A5F_05DE_51EB_5026L, + /* -284 */ 0x5614_106C_B11D_FA14L, 0x5518_D17E_A7EF_7352L, + /* -283 */ 0x44DC_D9F0_8DB1_94DDL, 0x2A7A_4132_1FF2_C2A8L, + /* -282 */ 0x6E2E_2980_E2B5_BAFBL, 0x5D90_6850_331E_043FL, + /* -281 */ 0x5824_EE00_B55E_2F2FL, 0x6473_86A6_8F4B_3699L, + /* -280 */ 0x4683_F19A_2AB1_BF59L, 0x36C2_D21E_D908_F87BL, + /* -279 */ 0x70D3_1C29_DDE9_3228L, 0x579E_1CFE_280E_5A5DL, + /* -278 */ 0x5A42_7CEE_4B20_F4EDL, 0x2C7E_7D98_200B_7B7EL, + /* -277 */ 0x4835_30BE_A280_C3F1L, 0x09FE_CAE0_19A2_C932L, + /* -276 */ 0x7388_4DFD_D0CE_064EL, 0x4331_4499_C29E_0EB6L, + /* -275 */ 0x5C6D_0B31_73D8_050BL, 0x4F5A_9D47_CEE4_D891L, + /* -274 */ 0x49F0_D5C1_2979_9DA2L, 0x72AE_E439_7250_AD41L, + /* -273 */ 0x764E_22CE_A8C2_95D1L, 0x377E_39F5_83B4_4868L, + /* -272 */ 0x5EA4_E8A5_53CE_DE41L, 0x12CB_6191_3629_D387L, + /* -271 */ 0x4BB7_2084_430B_E500L, 0x756F_8140_F821_7605L, + /* -270 */ 0x7925_00D3_9E79_6E67L, 0x6F18_CECE_59CF_233CL, + /* -269 */ 0x60EA_670F_B1FA_BEB9L, 0x3F47_0BD8_47D8_E8FDL, + /* -268 */ 0x4D88_5272_F4C8_9894L, 0x329F_3CAD_0647_20CAL, + /* -267 */ 0x7C0D_50B7_EE0D_C0EDL, 0x3765_2DE1_A3A5_0143L, + /* -266 */ 0x633D_DA2C_BE71_6724L, 0x2C50_F181_4FB7_3436L, + /* -265 */ 0x4F64_AE8A_31F4_5283L, 0x3D0D_8E01_0C92_902BL, + /* -264 */ 0x7F07_7DA9_E986_EA6BL, 0x7B48_E334_E0EA_8045L, + /* -263 */ 0x659F_97BB_2138_BB89L, 0x4907_1C2A_4D88_669DL, + /* -262 */ 0x514C_7962_80FA_2FA1L, 0x20D2_7CEE_A46D_1EE4L, + /* -261 */ 0x4109_FAB5_33FB_594DL, 0x670E_CA58_838A_7F1DL, + /* -260 */ 0x680F_F788_532B_C216L, 0x0B4A_DD5A_6C10_CB62L, + /* -259 */ 0x533F_F939_DC23_01ABL, 0x22A2_4AAE_BCDA_3C4EL, + /* -258 */ 0x4299_942E_49B5_9AEFL, 0x354E_A225_63E1_C9D8L, + /* -257 */ 0x6A8F_537D_42BC_2B18L, 0x554A_9D08_9FCF_A95AL, + /* -256 */ 0x553F_75FD_CEFC_EF46L, 0x776E_E406_E63F_BAAEL, + /* -255 */ 0x4432_C4CB_0BFD_8C38L, 0x5F8B_E99F_1E99_6225L, + /* -254 */ 0x6D1E_07AB_4662_79F4L, 0x3279_75CB_6428_9D08L, + /* -253 */ 0x574B_3955_D1E8_6190L, 0x2861_2B09_1CED_4A6DL, + /* -252 */ 0x45D5_C777_DB20_4E0DL, 0x06B4_226D_B0BD_D524L, + /* -251 */ 0x6FBC_7259_5E9A_167BL, 0x2453_6A49_1AC9_5506L, + /* -250 */ 0x5963_8EAD_E548_11FCL, 0x1D0F_883A_7BD4_4405L, + /* -249 */ 0x4782_D88B_1DD3_4196L, 0x4A72_D361_FCA9_D004L, + /* -248 */ 0x726A_F411_C952_028AL, 0x43EA_EBCF_FAA9_4CD3L, + /* -247 */ 0x5B88_C341_6DDB_353BL, 0x4FEF_230C_C887_70A9L, + /* -246 */ 0x493A_35CD_F17C_2A96L, 0x0CBF_4F3D_6D39_26EEL, + /* -245 */ 0x7529_EFAF_E8C6_AA89L, 0x6132_1862_485B_717CL, + /* -244 */ 0x5DBB_2626_53D2_2207L, 0x675B_46B5_06AF_8DFDL, + /* -243 */ 0x4AFC_1E85_0FDB_4E6CL, 0x52AF_6BC4_0559_3E64L, + /* -242 */ 0x77F9_CA6E_7FC5_4A47L, 0x377F_12D3_3BC1_FD6DL, + /* -241 */ 0x5FFB_0858_6637_6E9FL, 0x45FF_4242_9634_CABDL, + /* -240 */ 0x4CC8_D379_EB5F_8BB2L, 0x6B32_9B68_782A_3BCBL, + /* -239 */ 0x7ADA_EBF6_4565_AC51L, 0x2B84_2BDA_59DD_2C77L, + /* -238 */ 0x6248_BCC5_0451_56A7L, 0x3C69_BCAE_AE4A_89F9L, + /* -237 */ 0x4EA0_9704_0374_4552L, 0x6387_CA25_583B_A194L, + /* -236 */ 0x7DCD_BE6C_D253_A21EL, 0x05A6_103B_C05F_68EDL, + /* -235 */ 0x64A4_9857_0EA9_4E7EL, 0x37B8_0CFC_99E5_ED8AL, + /* -234 */ 0x5083_AD12_7221_0B98L, 0x2C93_3D96_E184_BE08L, + /* -233 */ 0x4069_5741_F4E7_3C79L, 0x7075_CADF_1AD0_9807L, + /* -232 */ 0x670E_F203_2171_FA5CL, 0x4D89_4498_2AE7_59A4L, + /* -231 */ 0x5272_5B35_B45B_2EB0L, 0x3E07_6A13_5585_E150L, + /* -230 */ 0x41F5_15C4_9048_F226L, 0x64D2_BB42_AAD1_810DL, + /* -229 */ 0x6988_22D4_1A0E_503EL, 0x07B7_9204_4482_6815L, + /* -228 */ 0x546C_E8A9_AE71_D9CBL, 0x1FC6_0E69_D068_5344L, + /* -227 */ 0x438A_53BA_F1F4_AE3CL, 0x196B_3EBB_0D20_429DL, + /* -226 */ 0x6C10_85F7_E987_7D2DL, 0x0F11_FDF8_1500_6A94L, + /* -225 */ 0x5673_9E5F_EE05_FDBDL, 0x58DB_3193_4400_5543L, + /* -224 */ 0x4529_4B7F_F19E_6497L, 0x60AF_5ADC_3666_AA9CL, + /* -223 */ 0x6EA8_78CC_B5CA_3A8CL, 0x344B_C493_8A3D_DDC7L, + /* -222 */ 0x5886_C70A_2B08_2ED6L, 0x5D09_6A0F_A1CB_17D2L, + /* -221 */ 0x46D2_38D4_EF39_BF12L, 0x173A_BB3F_B4A2_7975L, + /* -220 */ 0x7150_5AEE_4B8F_981DL, 0x0B91_2B99_2103_F588L, + /* -219 */ 0x5AA6_AF25_093F_ACE4L, 0x0940_EFAD_B403_2AD3L, + /* -218 */ 0x4885_58EA_6DCC_8A50L, 0x0767_2624_9002_88A9L, + /* -217 */ 0x7408_8E43_E2E0_DD4CL, 0x723E_A36D_B337_410EL, + /* -216 */ 0x5CD3_A503_1BE7_1770L, 0x5B65_4F8A_F5C5_CDA5L, + /* -215 */ 0x4A42_EA68_E31F_45F3L, 0x62B7_72D5_916B_0AEBL, + /* -214 */ 0x76D1_770E_3832_0986L, 0x0458_B7BC_1BDE_77DDL, + /* -213 */ 0x5F0D_F8D8_2CF4_D46BL, 0x1D13_C630_164B_9318L, + /* -212 */ 0x4C0B_2D79_BD90_A9EFL, 0x30DC_9E8C_DEA2_DC13L, + /* -211 */ 0x79AB_7BF5_FC1A_A97FL, 0x0160_FDAE_3104_9351L, + /* -210 */ 0x6155_FCC4_C9AE_EDFFL, 0x1AB3_FE24_F403_A90EL, + /* -209 */ 0x4DDE_63D0_A158_BE65L, 0x6229_981D_9002_EDA5L, + /* -208 */ 0x7C97_061A_9BC1_30A2L, 0x69DC_2695_B337_E2A1L, + /* -207 */ 0x63AC_04E2_1634_26E8L, 0x54B0_1EDE_28F9_821BL, + /* -206 */ 0x4FBC_D0B4_DE90_1F20L, 0x43C0_18B1_BA61_34E2L, + /* -205 */ 0x7F94_8121_6419_CB67L, 0x1F99_C11C_5D68_549DL, + /* -204 */ 0x6610_674D_E9AE_3C52L, 0x4C7B_00E3_7DED_107EL, + /* -203 */ 0x51A6_B90B_2158_3042L, 0x09FC_00B5_FE57_4065L, + /* -202 */ 0x4152_2DA2_8113_59CEL, 0x3B30_0091_9845_CD1DL, + /* -201 */ 0x6883_7C37_34EB_C2E3L, 0x784C_CDB5_C06F_AE95L, + /* -200 */ 0x539C_635F_5D89_68B6L, 0x2D0A_3E2B_0059_5877L, + /* -199 */ 0x42E3_82B2_B13A_BA2BL, 0x3DA1_CB55_99E1_1393L, + /* -198 */ 0x6B05_9DEA_B52A_C378L, 0x629C_7888_F634_EC1EL, + /* -197 */ 0x559E_17EE_F755_692DL, 0x3549_FA07_2B5D_89B1L, + /* -196 */ 0x447E_798B_F911_20F1L, 0x1107_FB38_EF7E_07C1L, + /* -195 */ 0x6D97_28DF_F4E8_34B5L, 0x01A6_5EC1_7F30_0C68L, + /* -194 */ 0x57AC_20B3_2A53_5D5DL, 0x4E1E_B234_65C0_09EDL, + /* -193 */ 0x4623_4D5C_21DC_4AB1L, 0x24E5_5B5D_1E33_3B24L, + /* -192 */ 0x7038_7BC6_9C93_AAB5L, 0x216E_F894_FD1E_C506L, + /* -191 */ 0x59C6_C96B_B076_222AL, 0x4DF2_6077_30E5_6A6CL, + /* -190 */ 0x47D2_3ABC_8D2B_4E88L, 0x3E5B_805F_5A51_21F0L, + /* -189 */ 0x72E9_F794_1512_1740L, 0x63C5_9A32_2A1B_697FL, + /* -188 */ 0x5BEE_5FA9_AA74_DF67L, 0x0304_7B5B_54E2_BACCL, + /* -187 */ 0x498B_7FBA_EEC3_E5ECL, 0x0269_FC49_10B5_623DL, + /* -186 */ 0x75AB_FF91_7E06_3CACL, 0x6A43_2D41_B455_69FBL, + /* -185 */ 0x5E23_32DA_CB38_308AL, 0x21CF_5767_C377_87FCL, + /* -184 */ 0x4B4F_5BE2_3C2C_F3A1L, 0x67D9_12B9_692C_6CCAL, + /* -183 */ 0x787E_F969_F9E1_85CFL, 0x595B_5128_A847_1476L, + /* -182 */ 0x6065_9454_C7E7_9E3FL, 0x6115_DA86_ED05_A9F8L, + /* -181 */ 0x4D1E_1043_D31F_B1CCL, 0x4DAB_1538_BD9E_2193L, + /* -180 */ 0x7B63_4D39_51CC_4FADL, 0x62AB_5527_95C9_CF52L, + /* -179 */ 0x62B5_D761_0E3D_0C8BL, 0x0222_AA86_116E_3F75L, + /* -178 */ 0x4EF7_DF80_D830_D6D5L, 0x4E82_2204_DABE_992AL, + /* -177 */ 0x7E59_659A_F381_57BCL, 0x1736_9CD4_9130_F510L, + /* -176 */ 0x6514_5148_C2CD_DFC9L, 0x5F5E_E3DD_40F3_F740L, + /* -175 */ 0x50DD_0DD3_CF0B_196EL, 0x1918_B64A_9A5C_C5CDL, + /* -174 */ 0x40B0_D7DC_A5A2_7ABEL, 0x4746_F83B_AEB0_9E3EL, + /* -173 */ 0x6781_5961_0903_F797L, 0x253E_59F9_1780_FD2FL, + /* -172 */ 0x52CD_E11A_6D9C_C612L, 0x50FE_AE60_DF9A_6426L, + /* -171 */ 0x423E_4DAE_BE17_04DBL, 0x5A65_584D_7FAE_B685L, + /* -170 */ 0x69FD_4917_968B_3AF9L, 0x10A2_26E2_65E4_573BL, + /* -169 */ 0x54CA_A0DF_ABA2_9594L, 0x0D4E_8581_EB1D_1295L, + /* -168 */ 0x43D5_4D7F_BC82_1143L, 0x243E_D134_BC17_4211L, + /* -167 */ 0x6C88_7BFF_9403_4ED2L, 0x06CA_E854_6025_3682L, + /* -166 */ 0x56D3_9666_1002_A574L, 0x6BD5_86A9_E684_2B9BL, + /* -165 */ 0x4576_11EB_4002_1DF7L, 0x0977_9EEE_5203_5616L, + /* -164 */ 0x6F23_4FDE_CCD0_2FF1L, 0x5BF2_97E3_B66B_BCEFL, + /* -163 */ 0x58E9_0CB2_3D73_598EL, 0x165B_ACB6_2B89_63F3L, + /* -162 */ 0x4720_D6F4_FDF5_E13EL, 0x4516_23C4_EFA1_1CC2L, + /* -161 */ 0x71CE_24BB_2FEF_CECAL, 0x3B56_9FA1_7F68_2E03L, + /* -160 */ 0x5B0B_5095_BFF3_0BD5L, 0x15DE_E61A_CC53_5803L, + /* -159 */ 0x48D5_DA11_665C_0977L, 0x2B18_B815_7042_ACCFL, + /* -158 */ 0x7489_5CE8_A3C6_758BL, 0x5E8D_F355_806A_AE18L, + /* -157 */ 0x5D3A_B0BA_1C9E_C46FL, 0x653E_5C44_66BB_BE7AL, + /* -156 */ 0x4A95_5A2E_7D4B_D059L, 0x3765_169D_1EFC_9861L, + /* -155 */ 0x7755_5D17_2EDF_B3C2L, 0x256E_8A94_FE60_F3CFL, + /* -154 */ 0x5F77_7DAC_257F_C301L, 0x6ABE_D543_FEB3_F63FL, + /* -153 */ 0x4C5F_97BC_EACC_9C01L, 0x3BCB_DDCF_FEF6_5E99L, + /* -152 */ 0x7A32_8C61_77AD_C668L, 0x5FAC_9619_97F0_975BL, + /* -151 */ 0x61C2_09E7_92F1_6B86L, 0x7FBD_44E1_465A_12AFL, + /* -150 */ 0x4E34_D4B9_425A_BC6BL, 0x7FCA_9D81_0514_DBBFL, + /* -149 */ 0x7D21_545B_9D5D_FA46L, 0x32DD_C8CE_6E87_C5FFL, + /* -148 */ 0x641A_A9E2_E44B_2E9EL, 0x5BE4_A0A5_2539_6B32L, + /* -147 */ 0x5015_54B5_836F_587EL, 0x7CB6_E6EA_842D_EF5CL, + /* -146 */ 0x4011_1091_35F2_AD32L, 0x3092_5255_368B_25E3L, + /* -145 */ 0x6681_B41B_8984_4850L, 0x4DB6_EA21_F0DE_A304L, + /* -144 */ 0x5201_5CE2_D469_D373L, 0x57C5_881B_2718_826AL, + /* -143 */ 0x419A_B0B5_76BB_0F8FL, 0x5FD1_39AF_527A_01EFL, + /* -142 */ 0x68F7_8122_5791_B27FL, 0x4C81_F5E5_50C3_364AL, + /* -141 */ 0x53F9_341B_7941_5B99L, 0x239B_2B1D_DA35_C508L, + /* -140 */ 0x432D_C349_2DCD_E2E1L, 0x02E2_88E4_AE91_6A6DL, + /* -139 */ 0x6B7C_6BA8_4949_6B01L, 0x516A_74A1_174F_10AEL, + /* -138 */ 0x55FD_22ED_076D_EF34L, 0x4121_F6E7_45D8_DA25L, + /* -137 */ 0x44CA_8257_3924_BF5DL, 0x1A81_9252_9E47_14EBL, + /* -136 */ 0x6E10_D08B_8EA1_322EL, 0x5D9C_1D50_FD3E_87DDL, + /* -135 */ 0x580D_73A2_D880_F4F2L, 0x17B0_1773_FDCB_9FE4L, + /* -134 */ 0x4671_294F_139A_5D8EL, 0x4626_7929_97D6_1984L, + /* -133 */ 0x70B5_0EE4_EC2A_2F4AL, 0x3D0A_5B75_BFBC_F59FL, + /* -132 */ 0x5A2A_7250_BCEE_8C3BL, 0x4A6E_AF91_6630_C47FL, + /* -131 */ 0x4821_F50D_63F2_09C9L, 0x21F2_260D_EB5A_36CCL, + /* -130 */ 0x7369_8815_6CB6_760EL, 0x6983_7016_455D_247AL, + /* -129 */ 0x5C54_6CDD_F091_F80BL, 0x6E02_C011_D117_5062L, + /* -128 */ 0x49DD_23E4_C074_C66FL, 0x719B_CCDB_0DAC_404EL, + /* -127 */ 0x762E_9FD4_6721_3D7FL, 0x68F9_47C4_E2AD_33B0L, + /* -126 */ 0x5E8B_B310_5280_FDFFL, 0x6D94_396A_4EF0_F627L, + /* -125 */ 0x4BA2_F5A6_A867_3199L, 0x3E10_2DEE_A58D_91B9L, + /* -124 */ 0x7904_BC3D_DA3E_B5C2L, 0x3019_E317_6F48_E927L, + /* -123 */ 0x60D0_9697_E1CB_C49BL, 0x4014_B5AC_5907_20ECL, + /* -122 */ 0x4D73_ABAC_B4A3_03AFL, 0x4CDD_5E23_7A6C_1A57L, + /* -121 */ 0x7BEC_45E1_2104_D2B2L, 0x47C8_969F_2A46_908AL, + /* -120 */ 0x6323_6B1A_80D0_A88EL, 0x6CA0_787F_5505_406FL, + /* -119 */ 0x4F4F_88E2_00A6_ED3FL, 0x0A19_F9FF_7737_66BFL, + /* -118 */ 0x7EE5_A7D0_010B_1531L, 0x5CF6_5CCB_F1F2_3DFEL, + /* -117 */ 0x6584_8640_00D5_AA8EL, 0x172B_7D6F_F4C1_CB32L, + /* -116 */ 0x5136_D1CC_CD77_BBA4L, 0x78EF_978C_C3CE_3C28L, + /* -115 */ 0x40F8_A7D7_0AC6_2FB7L, 0x13F2_DFA3_CFD8_3020L, + /* -114 */ 0x67F4_3FBE_77A3_7F8BL, 0x3984_9906_1959_E699L, + /* -113 */ 0x5329_CC98_5FB5_FFA2L, 0x6136_E0D1_ADE1_8548L, + /* -112 */ 0x4287_D6E0_4C91_994FL, 0x00F8_B3DA_F181_376DL, + /* -111 */ 0x6A72_F166_E0E8_F54BL, 0x1B27_862B_1C01_F247L, + /* -110 */ 0x5528_C11F_1A53_F76FL, 0x2F52_D1BC_1667_F506L, + /* -109 */ 0x4420_9A7F_4843_2C59L, 0x0C42_4163_451F_F738L, + /* -108 */ 0x6D00_F732_0D38_46F4L, 0x7A03_9BD2_0833_2526L, + /* -107 */ 0x5733_F8F4_D760_38C3L, 0x7B36_1641_A028_EA85L, + /* -106 */ 0x45C3_2D90_AC4C_FA36L, 0x2F5E_7834_8020_BB9EL, + /* -105 */ 0x6F9E_AF4D_E07B_29F0L, 0x4BCA_59ED_99CD_F8FCL, + /* -104 */ 0x594B_BF71_8062_87F3L, 0x563B_7B24_7B0B_2D96L, + /* -103 */ 0x476F_CC5A_CD1B_9FF6L, 0x11C9_2F50_626F_57ACL, + /* -102 */ 0x724C_7A2A_E1C5_CCBDL, 0x02DB_7EE7_03E5_5912L, + /* -101 */ 0x5B70_61BB_E7D1_7097L, 0x1BE2_CBEC_031D_E0DCL, + /* -100 */ 0x4926_B496_530D_F3ACL, 0x164F_0989_9C17_E716L, + /* -99 */ 0x750A_BA8A_1E7C_B913L, 0x3D4B_4275_C68C_A4F0L, + /* -98 */ 0x5DA2_2ED4_E530_940FL, 0x4AA2_9B91_6BA3_B726L, + /* -97 */ 0x4AE8_2577_1DC0_7672L, 0x6EE8_7C74_561C_9285L, + /* -96 */ 0x77D9_D58B_62CD_8A51L, 0x3173_FA53_BCFA_8408L, + /* -95 */ 0x5FE1_77A2_B571_3B74L, 0x278F_FB76_30C8_69A0L, + /* -94 */ 0x4CB4_5FB5_5DF4_2F90L, 0x1FA6_62C4_F3D3_87B3L, + /* -93 */ 0x7ABA_32BB_C986_B280L, 0x32A3_D13B_1FB8_D91FL, + /* -92 */ 0x622E_8EFC_A138_8ECDL, 0x0EE9_742F_4C93_E0E6L, + /* -91 */ 0x4E8B_A596_E760_723DL, 0x58BA_C359_0A0F_E71EL, + /* -90 */ 0x7DAC_3C24_A567_1D2FL, 0x412A_D228_1019_71C9L, + /* -89 */ 0x6489_C9B6_EAB8_E426L, 0x00EF_0E86_7347_8E3BL, + /* -88 */ 0x506E_3AF8_BBC7_1CEBL, 0x1A58_D86B_8F6C_71C9L, + /* -87 */ 0x4058_2F2D_6305_B0BCL, 0x1513_E056_0C56_C16EL, + /* -86 */ 0x66F3_7EAF_04D5_E793L, 0x3B53_0089_AD57_9BE2L, + /* -85 */ 0x525C_6558_D0AB_1FA9L, 0x15DC_006E_2446_164FL, + /* -84 */ 0x41E3_8447_0D55_B2EDL, 0x5E49_99F1_B69E_783FL, + /* -83 */ 0x696C_06D8_1555_EB15L, 0x7D42_8FE9_2430_C065L, + /* -82 */ 0x5456_6BE0_1111_88DEL, 0x3102_0CBA_835A_3384L, + /* -81 */ 0x4378_564C_DA74_6D7EL, 0x5A68_0A2E_CF7B_5C69L, + /* -80 */ 0x6BF3_BD47_C3ED_7BFDL, 0x770C_DD17_B25E_FA42L, + /* -79 */ 0x565C_976C_9CBD_FCCBL, 0x1270_B0DF_C1E5_9502L, + /* -78 */ 0x4516_DF8A_16FE_63D5L, 0x5B8D_5A4C_9B1E_10CEL, + /* -77 */ 0x6E8A_FF43_57FD_6C89L, 0x127B_C3AD_C4FC_E7B0L, + /* -76 */ 0x586F_329C_4664_56D4L, 0x0EC9_6957_D0CA_52F3L, + /* -75 */ 0x46BF_5BB0_3850_4576L, 0x3F07_8779_73D5_0F29L, + /* -74 */ 0x7132_2C4D_26E6_D58AL, 0x31A5_A58F_1FBB_4B75L, + /* -73 */ 0x5A8E_89D7_5252_446EL, 0x5AEA_EAD8_E62F_6F91L, + /* -72 */ 0x4872_07DF_750E_9D25L, 0x2F22_557A_51BF_8C74L, + /* -71 */ 0x73E9_A632_54E4_2EA2L, 0x1836_EF2A_1C65_AD86L, + /* -70 */ 0x5CBA_EB5B_771C_F21BL, 0x2CF8_BF54_E384_8AD2L, + /* -69 */ 0x4A2F_22AF_927D_8E7CL, 0x23FA_32AA_4F9D_3BDBL, + /* -68 */ 0x76B1_D118_EA62_7D93L, 0x5329_EAAA_18FB_92F8L, + /* -67 */ 0x5EF4_A747_21E8_6476L, 0x0F54_BBBB_472F_A8C6L, + /* -66 */ 0x4BF6_EC38_E7ED_1D2BL, 0x25DD_62FC_38F2_ED6CL, + /* -65 */ 0x798B_138E_3FE1_C845L, 0x22FB_D193_8E51_7BDFL, + /* -64 */ 0x613C_0FA4_FFE7_D36AL, 0x4F2F_DADC_71DA_C97FL, + /* -63 */ 0x4DC9_A61D_9986_42BBL, 0x58F3_157D_27E2_3ACCL, + /* -62 */ 0x7C75_D695_C270_6AC5L, 0x74B8_2261_D969_F7ADL, + /* -61 */ 0x6391_7877_CEC0_556BL, 0x1093_4EB4_ADEE_5FBEL, + /* -60 */ 0x4FA7_9393_0BCD_1122L, 0x4075_D890_8B25_1965L, + /* -59 */ 0x7F72_85B8_12E1_B504L, 0x00BC_8DB4_11D4_F56EL, + /* -58 */ 0x65F5_37C6_7581_5D9CL, 0x66FD_3E29_A7DD_9125L, + /* -57 */ 0x5190_F96B_9134_4AE3L, 0x6BFD_CB54_864A_DA84L, + /* -56 */ 0x4140_C789_40F6_A24FL, 0x6FFE_3C43_9EA2_486AL, + /* -55 */ 0x6867_A5A8_67F1_03B2L, 0x7FFD_2D38_FDD0_73DCL, + /* -54 */ 0x5386_1E20_5327_3628L, 0x6664_242D_97D9_F64AL, + /* -53 */ 0x42D1_B1B3_75B8_F820L, 0x51E9_B68A_DFE1_91D5L, + /* -52 */ 0x6AE9_1C52_55F4_C034L, 0x1CA9_2411_6635_B621L, + /* -51 */ 0x5587_49DB_77F7_0029L, 0x63BA_8341_1E91_5E81L, + /* -50 */ 0x446C_3B15_F992_6687L, 0x6962_029A_7EDA_B201L, + /* -49 */ 0x6D79_F823_28EA_3DA6L, 0x0F03_375D_97C4_5001L, + /* -48 */ 0x5794_C682_8721_CAEBL, 0x259C_2C4A_DFD0_4001L, + /* -47 */ 0x4610_9ECE_D281_6F22L, 0x5149_BD08_B30D_0001L, + /* -46 */ 0x701A_97B1_50CF_1837L, 0x3542_C80D_EB48_0001L, + /* -45 */ 0x59AE_DFC1_0D72_79C5L, 0x7768_A00B_22A0_0001L, + /* -44 */ 0x47BF_1967_3DF5_2E37L, 0x7920_8008_E880_0001L, + /* -43 */ 0x72CB_5BD8_6321_E38CL, 0x5B67_3341_7400_0001L, + /* -42 */ 0x5BD5_E313_8281_82D6L, 0x7C52_8F67_9000_0001L, + /* -41 */ 0x4977_E8DC_6867_9BDFL, 0x16A8_72B9_4000_0001L, + /* -40 */ 0x758C_A7C7_0D72_92FEL, 0x5773_EAC2_0000_0001L, + /* -39 */ 0x5E0A_1FD2_7128_7598L, 0x45F6_5568_0000_0001L, + /* -38 */ 0x4B3B_4CA8_5A86_C47AL, 0x04C5_1120_0000_0001L, + /* -37 */ 0x785E_E10D_5DA4_6D90L, 0x07A1_B500_0000_0001L, + /* -36 */ 0x604B_E73D_E483_8AD9L, 0x52E7_C400_0000_0001L, + /* -35 */ 0x4D09_85CB_1D36_08AEL, 0x0F1F_D000_0000_0001L, + /* -34 */ 0x7B42_6FAB_61F0_0DE3L, 0x31CC_8000_0000_0001L, + /* -33 */ 0x629B_8C89_1B26_7182L, 0x5B0A_0000_0000_0001L, + /* -32 */ 0x4EE2_D6D4_15B8_5ACEL, 0x7C08_0000_0000_0001L, + /* -31 */ 0x7E37_BE20_22C0_914BL, 0x1340_0000_0000_0001L, + /* -30 */ 0x64F9_64E6_8233_A76FL, 0x2900_0000_0000_0001L, + /* -29 */ 0x50C7_83EB_9B5C_85F2L, 0x5400_0000_0000_0001L, + /* -28 */ 0x409F_9CBC_7C4A_04C2L, 0x1000_0000_0000_0001L, + /* -27 */ 0x6765_C793_FA10_079DL, 0x0000_0000_0000_0001L, + /* -26 */ 0x52B7_D2DC_C80C_D2E4L, 0x0000_0000_0000_0001L, + /* -25 */ 0x422C_A8B0_A00A_4250L, 0x0000_0000_0000_0001L, + /* -24 */ 0x69E1_0DE7_6676_D080L, 0x0000_0000_0000_0001L, + /* -23 */ 0x54B4_0B1F_852B_DA00L, 0x0000_0000_0000_0001L, + /* -22 */ 0x43C3_3C19_3756_4800L, 0x0000_0000_0000_0001L, + /* -21 */ 0x6C6B_935B_8BBD_4000L, 0x0000_0000_0000_0001L, + /* -20 */ 0x56BC_75E2_D631_0000L, 0x0000_0000_0000_0001L, + /* -19 */ 0x4563_9182_44F4_0000L, 0x0000_0000_0000_0001L, + /* -18 */ 0x6F05_B59D_3B20_0000L, 0x0000_0000_0000_0001L, + /* -17 */ 0x58D1_5E17_6280_0000L, 0x0000_0000_0000_0001L, + /* -16 */ 0x470D_E4DF_8200_0000L, 0x0000_0000_0000_0001L, + /* -15 */ 0x71AF_D498_D000_0000L, 0x0000_0000_0000_0001L, + /* -14 */ 0x5AF3_107A_4000_0000L, 0x0000_0000_0000_0001L, + /* -13 */ 0x48C2_7395_0000_0000L, 0x0000_0000_0000_0001L, + /* -12 */ 0x746A_5288_0000_0000L, 0x0000_0000_0000_0001L, + /* -11 */ 0x5D21_DBA0_0000_0000L, 0x0000_0000_0000_0001L, + /* -10 */ 0x4A81_7C80_0000_0000L, 0x0000_0000_0000_0001L, + /* -9 */ 0x7735_9400_0000_0000L, 0x0000_0000_0000_0001L, + /* -8 */ 0x5F5E_1000_0000_0000L, 0x0000_0000_0000_0001L, + /* -7 */ 0x4C4B_4000_0000_0000L, 0x0000_0000_0000_0001L, + /* -6 */ 0x7A12_0000_0000_0000L, 0x0000_0000_0000_0001L, + /* -5 */ 0x61A8_0000_0000_0000L, 0x0000_0000_0000_0001L, + /* -4 */ 0x4E20_0000_0000_0000L, 0x0000_0000_0000_0001L, + /* -3 */ 0x7D00_0000_0000_0000L, 0x0000_0000_0000_0001L, + /* -2 */ 0x6400_0000_0000_0000L, 0x0000_0000_0000_0001L, + /* -1 */ 0x5000_0000_0000_0000L, 0x0000_0000_0000_0001L, + /* 0 */ 0x4000_0000_0000_0000L, 0x0000_0000_0000_0001L, + /* 1 */ 0x6666_6666_6666_6666L, 0x3333_3333_3333_3334L, + /* 2 */ 0x51EB_851E_B851_EB85L, 0x0F5C_28F5_C28F_5C29L, + /* 3 */ 0x4189_374B_C6A7_EF9DL, 0x5916_872B_020C_49BBL, + /* 4 */ 0x68DB_8BAC_710C_B295L, 0x74F0_D844_D013_A92BL, + /* 5 */ 0x53E2_D623_8DA3_C211L, 0x43F3_E037_0CDC_8755L, + /* 6 */ 0x431B_DE82_D7B6_34DAL, 0x698F_E692_70B0_6C44L, + /* 7 */ 0x6B5F_CA6A_F2BD_215EL, 0x0F4C_A41D_811A_46D4L, + /* 8 */ 0x55E6_3B88_C230_E77EL, 0x3F70_834A_CDAE_9F10L, + /* 9 */ 0x44B8_2FA0_9B5A_52CBL, 0x4C5A_02A2_3E25_4C0DL, + /* 10 */ 0x6DF3_7F67_5EF6_EADFL, 0x2D5C_D103_96A2_1347L, + /* 11 */ 0x57F5_FF85_E592_557FL, 0x3DE3_DA69_454E_75D3L, + /* 12 */ 0x465E_6604_B7A8_4465L, 0x7E4F_E1ED_D10B_9175L, + /* 13 */ 0x7097_09A1_25DA_0709L, 0x4A19_697C_81AC_1BEFL, + /* 14 */ 0x5A12_6E1A_84AE_6C07L, 0x54E1_2130_67BC_E326L, + /* 15 */ 0x480E_BE7B_9D58_566CL, 0x43E7_4DC0_52FD_8285L, + /* 16 */ 0x734A_CA5F_6226_F0ADL, 0x530B_AF9A_1E62_6A6DL, + /* 17 */ 0x5C3B_D519_1B52_5A24L, 0x426F_BFAE_7EB5_21F1L, + /* 18 */ 0x49C9_7747_490E_AE83L, 0x4EBF_CC8B_9890_E7F4L, + /* 19 */ 0x760F_253E_DB4A_B0D2L, 0x4ACC_7A78_F41B_0CBAL, + /* 20 */ 0x5E72_8432_4908_8D75L, 0x223D_2EC7_29AF_3D62L, + /* 21 */ 0x4B8E_D028_3A6D_3DF7L, 0x34FD_BF05_BAF2_9781L, + /* 22 */ 0x78E4_8040_5D7B_9658L, 0x54C9_31A2_C4B7_58CFL, + /* 23 */ 0x60B6_CD00_4AC9_4513L, 0x5D6D_C14F_03C5_E0A5L, + /* 24 */ 0x4D5F_0A66_A23A_9DA9L, 0x3124_9AA5_9C9E_4D51L, + /* 25 */ 0x7BCB_43D7_69F7_62A8L, 0x4EA0_F76F_60FD_4882L, + /* 26 */ 0x6309_0312_BB2C_4EEDL, 0x254D_92BF_80CA_A068L, + /* 27 */ 0x4F3A_68DB_C8F0_3F24L, 0x1DD7_A899_33D5_4D20L, + /* 28 */ 0x7EC3_DAF9_4180_6506L, 0x62F2_A75B_8622_1500L, + /* 29 */ 0x6569_7BFA_9ACD_1D9FL, 0x025B_B916_04E8_10CDL, + /* 30 */ 0x5121_2FFB_AF0A_7E18L, 0x6849_60DE_6A53_40A4L, + /* 31 */ 0x40E7_5996_25A1_FE7AL, 0x203A_B3E5_21DC_33B6L, + /* 32 */ 0x67D8_8F56_A29C_CA5DL, 0x19F7_863B_6960_52BDL, + /* 33 */ 0x5313_A5DE_E87D_6EB0L, 0x7B2C_6B62_BAB3_7564L, + /* 34 */ 0x4276_1E4B_ED31_255AL, 0x2F56_BC4E_FBC2_C450L, + /* 35 */ 0x6A56_96DF_E1E8_3BC3L, 0x6557_93B1_92D1_3A1AL, + /* 36 */ 0x5512_124C_B4B9_C969L, 0x3779_42F4_7574_2E7BL, + /* 37 */ 0x440E_750A_2A2E_3ABAL, 0x5F94_3590_5DF6_8B96L, + /* 38 */ 0x6CE3_EE76_A9E3_912AL, 0x65B9_EF4D_6324_1289L, + /* 39 */ 0x571C_BEC5_54B6_0DBBL, 0x6AFB_25D7_8283_4207L, + /* 40 */ 0x45B0_989D_DD5E_7163L, 0x08C8_EB12_CECF_6806L, + /* 41 */ 0x6F80_F42F_C897_1BD1L, 0x5ADB_11B7_B14B_D9A3L, + /* 42 */ 0x5933_F68C_A078_E30EL, 0x157C_0E2C_8DD6_47B5L, + /* 43 */ 0x475C_C53D_4D2D_8271L, 0x5DFC_D823_A4AB_6C91L, + /* 44 */ 0x722E_0862_1515_9D82L, 0x632E_269F_6DDF_141BL, + /* 45 */ 0x5B58_06B4_DDAA_E468L, 0x4F58_1EE5_F17F_4349L, + /* 46 */ 0x4913_3890_B155_8386L, 0x72AC_E584_C132_9C3BL, + /* 47 */ 0x74EB_8DB4_4EEF_38D7L, 0x6AAE_3C07_9B84_2D2AL, + /* 48 */ 0x5D89_3E29_D8BF_60ACL, 0x5558_3006_1603_5755L, + /* 49 */ 0x4AD4_31BB_13CC_4D56L, 0x7779_C004_DE69_12ABL, + /* 50 */ 0x77B9_E92B_52E0_7BBEL, 0x258F_99A1_63DB_5111L, + /* 51 */ 0x5FC7_EDBC_424D_2FCBL, 0x37A6_1481_1CAF_740DL, + /* 52 */ 0x4C9F_F163_683D_BFD5L, 0x7951_AA00_E3BF_900BL, + /* 53 */ 0x7A99_8238_A6C9_32EFL, 0x754F_7667_D2CC_19ABL, + /* 54 */ 0x6214_682D_523A_8F26L, 0x2AA5_F853_0F09_AE22L, + /* 55 */ 0x4E76_B9BD_DB62_0C1EL, 0x5551_9375_A5A1_581BL, + /* 56 */ 0x7D8A_C2C9_5F03_4697L, 0x3BB5_B8BC_3C35_59C5L, + /* 57 */ 0x646F_023A_B269_0545L, 0x7C91_6096_9691_149EL, + /* 58 */ 0x5058_CE95_5B87_376BL, 0x16DA_B3AB_ABA7_43B2L, + /* 59 */ 0x4047_0BAA_AF9F_5F88L, 0x78AE_F622_EFB9_02F5L, + /* 60 */ 0x66D8_12AA_B298_98DBL, 0x0DE4_BD04_B2C1_9E54L, + /* 61 */ 0x5246_7555_5BAD_4715L, 0x57EA_30D0_8F01_4B76L, + /* 62 */ 0x41D1_F777_7C8A_9F44L, 0x4654_F3DA_0C01_092CL, + /* 63 */ 0x694F_F258_C744_3207L, 0x23BB_1FC3_4668_0EACL, + /* 64 */ 0x543F_F513_D29C_F4D2L, 0x4FC8_E635_D1EC_D88AL, + /* 65 */ 0x4366_5DA9_754A_5D75L, 0x263A_51C4_A7F0_AD3BL, + /* 66 */ 0x6BD6_FC42_5543_C8BBL, 0x56C3_B607_731A_AEC4L, + /* 67 */ 0x5645_969B_7769_6D62L, 0x789C_919F_8F48_8BD0L, + /* 68 */ 0x4504_787C_5F87_8AB5L, 0x46E3_A7B2_D906_D640L, + /* 69 */ 0x6E6D_8D93_CC0C_1122L, 0x3E39_0C51_5B3E_239AL, + /* 70 */ 0x5857_A476_3CD6_741BL, 0x4B60_D6A7_7C31_B615L, + /* 71 */ 0x46AC_8391_CA45_29AFL, 0x55E7_121F_968E_2B44L, + /* 72 */ 0x7114_05B6_106E_A919L, 0x0971_B698_F0E3_786DL, + /* 73 */ 0x5A76_6AF8_0D25_5414L, 0x078E_2BAD_8D82_C6BDL, + /* 74 */ 0x485E_BBF9_A41D_DCDCL, 0x6C71_BC8A_D79B_D231L, + /* 75 */ 0x73CA_C65C_39C9_6161L, 0x2D82_C744_8C2C_8382L, + /* 76 */ 0x5CA2_3849_C7D4_4DE7L, 0x3E02_3903_A356_CF9BL, + /* 77 */ 0x4A1B_603B_0643_7185L, 0x7E68_2D9C_82AB_D949L, + /* 78 */ 0x7692_3391_A39F_1C09L, 0x4A40_48FA_6AAC_8EDBL, + /* 79 */ 0x5EDB_5C74_82E5_B007L, 0x5500_3A61_EEF0_7249L, + /* 80 */ 0x4BE2_B05D_3584_8CD2L, 0x7733_61E7_F259_F507L, + /* 81 */ 0x796A_B3C8_55A0_E151L, 0x3EB8_9CA6_508F_EE71L, + /* 82 */ 0x6122_296D_114D_810DL, 0x7EFA_16EB_73A6_585BL, + /* 83 */ 0x4DB4_EDF0_DAA4_673EL, 0x3261_ABEF_8FB8_46AFL, + /* 84 */ 0x7C54_AFE7_C43A_3ECAL, 0x1D69_1318_E5F3_A44BL, + /* 85 */ 0x6376_F31F_D02E_98A1L, 0x6454_0F47_1E5C_836FL, + /* 86 */ 0x4F92_5C19_7358_7A1BL, 0x0376_729F_4B7D_35F3L, + /* 87 */ 0x7F50_935B_EBC0_C35EL, 0x38BD_8432_1261_EFEBL, + /* 88 */ 0x65DA_0F7C_BC9A_35E5L, 0x13CA_D028_0EB4_BFEFL, + /* 89 */ 0x517B_3F96_FD48_2B1DL, 0x5CA2_4020_0BC3_CCBFL, + /* 90 */ 0x412F_6612_6439_BC17L, 0x63B5_0019_A303_0A33L, + /* 91 */ 0x684B_D683_D38F_9359L, 0x1F88_0029_04D1_A9EAL, + /* 92 */ 0x536F_DECF_DC72_DC47L, 0x32D3_3354_03DA_EE55L, + /* 93 */ 0x42BF_E573_16C2_49D2L, 0x5BDC_2910_0315_8B77L, + /* 94 */ 0x6ACC_A251_BE03_A951L, 0x12F9_DB4C_D1BC_1258L, + /* 95 */ 0x5570_81DA_FE69_5440L, 0x7594_AF70_A7C9_A847L, + /* 96 */ 0x445A_017B_FEBA_A9CDL, 0x4476_F2C0_863A_ED06L, + /* 97 */ 0x6D5C_CF2C_CAC4_42E2L, 0x3A57_EACD_A391_7B3CL, + /* 98 */ 0x577D_728A_3BD0_3581L, 0x7B79_88A4_82DA_C8FDL, + /* 99 */ 0x45FD_F53B_630C_F79BL, 0x15FA_D3B6_CF15_6D97L, + /* 100 */ 0x6FFC_BB92_3814_BF5EL, 0x565E_1F8A_E4EF_15BEL, + /* 101 */ 0x5996_FC74_F9AA_32B2L, 0x11E4_E608_B725_AAFFL, + /* 102 */ 0x47AB_FD2A_6154_F55BL, 0x27EA_51A0_9284_88CCL, + /* 103 */ 0x72AC_C843_CEEE_555EL, 0x7310_829A_8407_4146L, + /* 104 */ 0x5BBD_6D03_0BF1_DDE5L, 0x4273_9BAE_D005_CDD2L, + /* 105 */ 0x4964_5735_A327_E4B7L, 0x4EC2_E2F2_4004_A4A8L, + /* 106 */ 0x756D_5855_D1D9_6DF2L, 0x4AD1_6B1D_333A_A10CL, + /* 107 */ 0x5DF1_1377_DB14_57F5L, 0x2241_227D_C295_4DA3L, + /* 108 */ 0x4B27_42C6_48DD_132AL, 0x4E9A_81FE_3544_3E1CL, + /* 109 */ 0x783E_D13D_4161_B844L, 0x175D_9CC9_EED3_9694L, + /* 110 */ 0x6032_40FD_CDE7_C69CL, 0x7917_B0A1_8BDC_7876L, + /* 111 */ 0x4CF5_00CB_0B1F_D217L, 0x1412_F3B4_6FE3_9392L, + /* 112 */ 0x7B21_9ADE_7832_E9BEL, 0x5351_85ED_7FD2_85B6L, + /* 113 */ 0x6281_48B1_F9C2_5498L, 0x42A7_9E57_9975_37C5L, + /* 114 */ 0x4ECD_D3C1_949B_76E0L, 0x3552_E512_E12A_9304L, + /* 115 */ 0x7E16_1F9C_20F8_BE33L, 0x6EEB_081E_3510_EB39L, + /* 116 */ 0x64DE_7FB0_1A60_9829L, 0x3F22_6CE4_F740_BC2EL, + /* 117 */ 0x50B1_FFC0_151A_1354L, 0x3281_F0B7_2C33_C9BEL, + /* 118 */ 0x408E_6633_4414_DC43L, 0x4201_8D5F_568F_D498L, + /* 119 */ 0x674A_3D1E_D354_939FL, 0x1CCF_4898_8A7F_BA8DL, + /* 120 */ 0x52A1_CA7F_0F76_DC7FL, 0x30A5_D3AD_3B99_620BL, + /* 121 */ 0x421B_0865_A5F8_B065L, 0x73B7_DC8A_9614_4E6FL, + /* 122 */ 0x69C4_DA3C_3CC1_1A3CL, 0x52BF_C744_2353_B0B1L, + /* 123 */ 0x549D_7B63_63CD_AE96L, 0x7566_3903_4F76_26F4L, + /* 124 */ 0x43B1_2F82_B63E_2545L, 0x4451_C735_D92B_525DL, + /* 125 */ 0x6C4E_B26A_BD30_3BA2L, 0x3A1C_71EF_C1DE_EA2EL, + /* 126 */ 0x56A5_5B88_9759_C94EL, 0x61B0_5B26_34B2_54F2L, + /* 127 */ 0x4551_1606_DF7B_0772L, 0x1AF3_7C1E_908E_AA5BL, + /* 128 */ 0x6EE8_233E_325E_7250L, 0x2B1F_2CFD_B417_76F8L, + /* 129 */ 0x58B9_B5CB_5B7E_C1D9L, 0x6F4C_23FE_29AC_5F2DL, + /* 130 */ 0x46FA_F7D5_E2CB_CE47L, 0x72A3_4FFE_87BD_18F1L, + /* 131 */ 0x7191_8C89_6ADF_B073L, 0x0438_7FFD_A5FB_5B1BL, + /* 132 */ 0x5ADA_D6D4_557F_C05CL, 0x0360_6664_84C9_15AFL, + /* 133 */ 0x48AF_1243_7799_66B0L, 0x02B3_851D_3707_448CL, + /* 134 */ 0x744B_506B_F28F_0AB3L, 0x1DEC_082E_BE72_0746L, + /* 135 */ 0x5D09_0D23_2872_6EF5L, 0x64BC_D358_985B_3905L, + /* 136 */ 0x4A6D_A41C_205B_8BF7L, 0x6A30_A913_AD15_C738L, + /* 137 */ 0x7715_D360_33C5_ACBFL, 0x5D1A_A81F_7B56_0B8CL, + /* 138 */ 0x5F44_A919_C304_8A32L, 0x7DAE_ECE5_FC44_D609L, + /* 139 */ 0x4C36_EDAE_359D_3B5BL, 0x7E25_8A51_969D_7808L, + /* 140 */ 0x79F1_7C49_EF61_F893L, 0x16A2_76E8_F0FB_F33FL, + /* 141 */ 0x618D_FD07_F2B4_C6DCL, 0x121B_9253_F3FC_C299L, + /* 142 */ 0x4E0B_30D3_2890_9F16L, 0x41AF_A843_2997_0214L, + /* 143 */ 0x7CDE_B485_0DB4_31BDL, 0x4F7F_739E_A8F1_9CEDL, + /* 144 */ 0x63E5_5D37_3E29_C164L, 0x3F99_294B_BA5A_E3F1L, + /* 145 */ 0x4FEA_B0F8_FE87_CDE9L, 0x7FAD_BAA2_FB7B_E98DL, + /* 146 */ 0x7FDD_E7F4_CA72_E30FL, 0x7F7C_5DD1_925F_DC15L, + /* 147 */ 0x664B_1FF7_085B_E8D9L, 0x4C63_7E41_41E6_49ABL, + /* 148 */ 0x51D5_B32C_06AF_ED7AL, 0x704F_9834_34B8_3AEFL, + /* 149 */ 0x4177_C289_9EF3_2462L, 0x26A6_135C_F6F9_C8BFL, + /* 150 */ 0x68BF_9DA8_FE51_D3D0L, 0x3DD6_8561_8B29_4132L, + /* 151 */ 0x53CC_7E20_CB74_A973L, 0x4B12_044E_08ED_CDC2L, + /* 152 */ 0x4309_FE80_A2C3_BAC2L, 0x6F41_9D0B_3A57_D7CEL, + /* 153 */ 0x6B43_30CD_D139_2AD1L, 0x3202_94DE_C3BF_BFB0L, + /* 154 */ 0x55CF_5A3E_40FA_88A7L, 0x419B_AA4B_CFCC_995AL, + /* 155 */ 0x44A5_E1CB_672E_D3B9L, 0x1AE2_EEA3_0CA3_ADE1L, + /* 156 */ 0x6DD6_3612_3EB1_52C1L, 0x77D1_7DD1_ADD2_AFCFL, + /* 157 */ 0x57DE_91A8_3227_7567L, 0x7974_64A7_BE42_263FL, + /* 158 */ 0x464B_A7B9_C1B9_2AB9L, 0x4790_5086_31CE_84FFL, + /* 159 */ 0x7079_0C5C_6928_445CL, 0x0C1A_1A70_4FB0_D4CCL, + /* 160 */ 0x59FA_7049_EDB9_D049L, 0x567B_4859_D95A_43D6L, + /* 161 */ 0x47FB_8D07_F161_736EL, 0x11FC_39E1_7AAE_9CABL, + /* 162 */ 0x732C_14D9_8235_857DL, 0x032D_2968_C44A_9445L, + /* 163 */ 0x5C23_43E1_34F7_9DFDL, 0x4F57_5453_D03B_A9D1L, + /* 164 */ 0x49B5_CFE7_5D92_E4CAL, 0x72AC_4376_402F_BB0EL, + /* 165 */ 0x75EF_B30B_C8EB_07ABL, 0x0446_D256_CD19_2B49L, + /* 166 */ 0x5E59_5C09_6D88_D2EFL, 0x1D05_7512_3DAD_BC3AL, + /* 167 */ 0x4B7A_B007_8AD3_DBF2L, 0x4A6A_C40E_97BE_302FL, + /* 168 */ 0x78C4_4CD8_DE1F_C650L, 0x7711_39B0_F2C9_E6B1L, + /* 169 */ 0x609D_0A47_1819_6B73L, 0x78DA_948D_8F07_EBC1L, + /* 170 */ 0x4D4A_6E9F_467A_BC5CL, 0x60AE_DD3E_0C06_5634L, + /* 171 */ 0x7BAA_4A98_70C4_6094L, 0x344A_FB96_79A3_BD20L, + /* 172 */ 0x62EE_A213_8D69_E6DDL, 0x103B_FC78_614F_CA80L, + /* 173 */ 0x4F25_4E76_0ABB_1F17L, 0x2696_6393_810C_A200L, + /* 174 */ 0x7EA2_1723_445E_9825L, 0x2423_D285_9B47_6999L, + /* 175 */ 0x654E_78E9_037E_E01DL, 0x69B6_4204_7C39_2148L, + /* 176 */ 0x510B_93ED_9C65_8017L, 0x6E2B_6803_9694_1AA0L, + /* 177 */ 0x40D6_0FF1_49EA_CCDFL, 0x71BC_5336_1210_154DL, + /* 178 */ 0x67BC_E64E_DCAA_E166L, 0x1C60_8523_5019_BBAEL, + /* 179 */ 0x52FD_850B_E3BB_E784L, 0x7D1A_041C_4014_9625L, + /* 180 */ 0x4264_6A6F_E963_1F9DL, 0x4A7B_367D_0010_781DL, + /* 181 */ 0x6A3A_43E6_4238_3295L, 0x5D91_F0C8_001A_59C8L, + /* 182 */ 0x54FB_6985_01C6_8EDEL, 0x17A7_F3D3_3348_47D4L, + /* 183 */ 0x43FC_546A_67D2_0BE4L, 0x7953_2975_C2A0_3976L, + /* 184 */ 0x6CC6_ED77_0C83_463BL, 0x0EEB_7589_3766_C256L, + /* 185 */ 0x5705_8AC5_A39C_382FL, 0x2589_2AD4_2C52_3512L, + /* 186 */ 0x459E_089E_1C7C_F9BFL, 0x37A0_EF10_2374_F742L, + /* 187 */ 0x6F63_40FC_FA61_8F98L, 0x5901_7E80_38BB_2536L, + /* 188 */ 0x591C_33FD_951A_D946L, 0x7A67_9866_93C8_EA91L, + /* 189 */ 0x4749_C331_4415_7A9FL, 0x151F_AD1E_DCA0_BBA8L, + /* 190 */ 0x720F_9EB5_39BB_F765L, 0x0832_AE97_C767_92A5L, + /* 191 */ 0x5B3F_B22A_9496_5F84L, 0x068E_F213_05EC_7551L, + /* 192 */ 0x48FF_C1BB_AA11_E603L, 0x1ED8_C1A8_D189_F774L, + /* 193 */ 0x74CC_692C_434F_D66BL, 0x4AF4_690E_1C0F_F253L, + /* 194 */ 0x5D70_5423_690C_AB89L, 0x225D_20D8_1673_2843L, + /* 195 */ 0x4AC0_434F_873D_5607L, 0x3517_4D79_AB8F_5369L, + /* 196 */ 0x779A_054C_0B95_5672L, 0x21BE_E25C_45B2_1F0EL, + /* 197 */ 0x5FAE_6AA3_3C77_785BL, 0x3498_B516_9E28_18D8L, + /* 198 */ 0x4C8B_8882_96C5_F9E2L, 0x5D46_F745_4B53_4713L, + /* 199 */ 0x7A78_DA6A_8AD6_5C9DL, 0x7BA4_BED5_4552_0B52L, + /* 200 */ 0x61FA_4855_3BDE_B07EL, 0x2FB6_FF11_0441_A2A8L, + /* 201 */ 0x4E61_D377_6318_8D31L, 0x72F8_CC0D_9D01_4EEDL, + /* 202 */ 0x7D69_5258_9E8D_AEB6L, 0x1E5A_E015_C802_17E1L, + /* 203 */ 0x6454_41E0_7ED7_BEF8L, 0x1848_B344_A001_ACB4L, + /* 204 */ 0x5043_67E6_CBDF_CBF9L, 0x603A_2903_B334_8A2AL, + /* 205 */ 0x4035_ECB8_A319_6FFBL, 0x002E_8736_28F6_D4EEL, + /* 206 */ 0x66BC_ADF4_3828_B32BL, 0x19E4_0B89_DB24_87E3L, + /* 207 */ 0x5230_8B29_C686_F5BCL, 0x14B6_6FA1_7C1D_3983L, + /* 208 */ 0x41C0_6F54_9ED2_5E30L, 0x1091_F2E7_967D_C79CL, + /* 209 */ 0x6933_E554_3150_96B3L, 0x341C_B7D8_F0C9_3F5FL, + /* 210 */ 0x5429_8443_5AA6_DEF5L, 0x767D_5FE0_C0A0_FF80L, + /* 211 */ 0x4354_69CF_7BB8_B25EL, 0x2B97_7FE7_0080_CC66L, + /* 212 */ 0x6BBA_42E5_92C1_1D63L, 0x5F58_CCA4_CD9A_E0A3L, + /* 213 */ 0x562E_9BEA_DBCD_B11CL, 0x4C47_0A1D_7148_B3B6L, + /* 214 */ 0x44F2_1655_7CA4_8DB0L, 0x3D05_A1B1_276D_5C92L, + /* 215 */ 0x6E50_23BB_FAA0_E2B3L, 0x7B3C_35E8_3F15_60E9L, + /* 216 */ 0x5840_1C96_621A_4EF6L, 0x2F63_5E53_65AA_B3EDL, + /* 217 */ 0x4699_B078_4E7B_725EL, 0x591C_4B75_EAEE_F658L, + /* 218 */ 0x70F5_E726_E3F8_B6FDL, 0x74FA_1256_44B1_8A26L, + /* 219 */ 0x5A5E_5285_832D_5F31L, 0x43FB_41DE_9D5A_D4EBL, + /* 220 */ 0x484B_7537_9C24_4C27L, 0x4FFC_34B2_177B_DD89L, + /* 221 */ 0x73AB_EEBF_603A_1372L, 0x4CC6_BAB6_8BF9_6274L, + /* 222 */ 0x5C89_8BCC_4CFB_42C2L, 0x0A38_955E_D661_1B90L, + /* 223 */ 0x4A07_A309_D72F_689BL, 0x21C6_DDE5_784D_AFA7L, + /* 224 */ 0x7672_9E76_2518_A75EL, 0x693E_2FD5_8D49_190BL, + /* 225 */ 0x5EC2_185E_8413_B918L, 0x5431_BFDE_0AA0_E0D5L, + /* 226 */ 0x4BCE_79E5_3676_2DADL, 0x29C1_664B_3BB3_E711L, + /* 227 */ 0x794A_5CA1_F0BD_15E2L, 0x0F9B_D6DE_C5EC_A4E8L, + /* 228 */ 0x6108_4A1B_26FD_AB1BL, 0x2616_457F_04BD_50BAL, + /* 229 */ 0x4DA0_3B48_EBFE_227CL, 0x1E78_3798_D097_73C8L, + /* 230 */ 0x7C33_920E_4663_6A60L, 0x30C0_58F4_80F2_52D9L, + /* 231 */ 0x635C_74D8_384F_884DL, 0x0D66_AD90_6728_4247L, + /* 232 */ 0x4F7D_2A46_9372_D370L, 0x711E_F140_5286_9B6CL, + /* 233 */ 0x7F2E_AA0A_8584_8581L, 0x34FE_4ECD_50D7_5F14L, + /* 234 */ 0x65BE_EE6E_D136_D134L, 0x2A65_0BD7_73DF_7F43L, + /* 235 */ 0x5165_8B8B_DA92_40F6L, 0x551D_A312_C319_329CL, + /* 236 */ 0x411E_093C_AEDB_672BL, 0x5DB1_4F42_35AD_C217L, + /* 237 */ 0x6830_0EC7_7E2B_D845L, 0x7C4E_E536_BC49_368AL, + /* 238 */ 0x5359_A56C_64EF_E037L, 0x7D0B_EA92_303A_9208L, + /* 239 */ 0x42AE_1DF0_50BF_E693L, 0x173C_BBA8_2695_41A0L, + /* 240 */ 0x6AB0_2FE6_E799_70EBL, 0x3EC7_92A6_A422_029AL, + /* 241 */ 0x5559_BFEB_EC7A_C0BCL, 0x3239_421E_E9B4_CEE1L, + /* 242 */ 0x4447_CCBC_BD2F_0096L, 0x5B61_01B2_5490_A581L, + /* 243 */ 0x6D3F_ADFA_C84B_3424L, 0x2BCE_691D_541A_A268L, + /* 244 */ 0x5766_24C8_A03C_29B6L, 0x563E_BA7D_DCE2_1B87L, + /* 245 */ 0x45EB_50A0_8030_215EL, 0x7832_2ECB_171B_4939L, + /* 246 */ 0x6FDE_E767_3380_3564L, 0x59E9_E478_24F8_7527L, + /* 247 */ 0x597F_1F85_C2CC_F783L, 0x6187_E9F9_B72D_2A86L, + /* 248 */ 0x4798_E604_9BD7_2C69L, 0x346C_BB2E_2C24_2205L, + /* 249 */ 0x728E_3CD4_2C8B_7A42L, 0x20AD_F849_E039_D007L, + /* 250 */ 0x5BA4_FD76_8A09_2E9BL, 0x33BE_603B_19C7_D99FL, + /* 251 */ 0x4950_CAC5_3B3A_8BAFL, 0x42FE_B362_7B06_47B3L, + /* 252 */ 0x754E_113B_91F7_45E5L, 0x5197_856A_5E70_72B8L, + /* 253 */ 0x5DD8_0DC9_4192_9E51L, 0x27AC_6ABB_7EC0_5BC6L, + /* 254 */ 0x4B13_3E3A_9ADB_B1DAL, 0x52F0_5562_CBCD_1638L, + /* 255 */ 0x781E_C9F7_5E2C_4FC4L, 0x1E4D_556A_DFAE_89F3L, + /* 256 */ 0x6018_A192_B1BD_0C9CL, 0x7EA4_4455_7FBE_D4C3L, + /* 257 */ 0x4CE0_8142_27CA_707DL, 0x4BB6_9D11_32FF_109CL, + /* 258 */ 0x7B00_CED0_3FAA_4D95L, 0x5F8A_94E8_5198_1A93L, + /* 259 */ 0x6267_0BD9_CC88_3E11L, 0x32D5_43ED_0E13_4875L, + /* 260 */ 0x4EB8_D647_D6D3_64DAL, 0x5BDD_CFF0_D80F_6D2BL, + /* 261 */ 0x7DF4_8A0C_8AEB_D491L, 0x12FC_7FE7_C018_AEABL, + /* 262 */ 0x64C3_A1A3_A256_43A7L, 0x28C9_FFEC_99AD_5889L, + /* 263 */ 0x509C_814F_B511_CFB9L, 0x0707_FFF0_7AF1_13A1L, + /* 264 */ 0x407D_343F_C40E_3FC7L, 0x1F39_998D_2F27_42E7L, + /* 265 */ 0x672E_B9FF_A016_CC71L, 0x7EC2_8F48_4B72_04A4L, + /* 266 */ 0x528B_C7FF_B345_705BL, 0x189B_A5D3_6F8E_6A1DL, + /* 267 */ 0x4209_6CCC_8F6A_C048L, 0x7A16_1E42_BFA5_21B1L, + /* 268 */ 0x69A8_AE14_18AA_CD41L, 0x4356_96D1_32A1_CF81L, + /* 269 */ 0x5486_F1A9_AD55_7101L, 0x1C45_4574_2881_72CEL, + /* 270 */ 0x439F_27BA_F111_2734L, 0x169D_D129_BA01_28A5L, + /* 271 */ 0x6C31_D92B_1B4E_A520L, 0x242F_B50F_9001_DAA1L, + /* 272 */ 0x568E_4755_AF72_1DB3L, 0x368C_90D9_4001_7BB4L, + /* 273 */ 0x453E_9F77_BF8E_7E29L, 0x120A_0D7A_999A_C95DL, + /* 274 */ 0x6ECA_98BF_98E3_FD0EL, 0x5010_1590_F5C4_7561L, + /* 275 */ 0x58A2_13CC_7A4F_FDA5L, 0x2673_4473_F7D0_5DE8L, + /* 276 */ 0x46E8_0FD6_C83F_FE1DL, 0x6B8F_69F6_5FD9_E4B9L, + /* 277 */ 0x7173_4C8A_D9FF_FCFCL, 0x45B2_4323_CC8F_D45CL, + /* 278 */ 0x5AC2_A3A2_47FF_FD96L, 0x6AF5_0283_0A0C_A9E3L, + /* 279 */ 0x489B_B61B_6CCC_CADFL, 0x08C4_0202_6E70_87E9L, + /* 280 */ 0x742C_5692_47AE_1164L, 0x746C_D003_E3E7_3FDBL, + /* 281 */ 0x5CF0_4541_D2F1_A783L, 0x76BD_7336_4FEC_3315L, + /* 282 */ 0x4A59_D101_758E_1F9CL, 0x5EFD_F5C5_0CBC_F5ABL, + /* 283 */ 0x76F6_1B35_88E3_65C7L, 0x4B2F_EFA1_ADFB_22ABL, + /* 284 */ 0x5F2B_48F7_A0B5_EB06L, 0x08F3_261A_F195_B555L, + /* 285 */ 0x4C22_A0C6_1A2B_226BL, 0x20C2_84E2_5ADE_2AABL, + /* 286 */ 0x79D1_013C_F6AB_6A45L, 0x1AD0_D49D_5E30_4444L, + /* 287 */ 0x6174_00FD_9222_BB6AL, 0x48A7_107D_E4F3_69D0L, + /* 288 */ 0x4DF6_6731_41B5_62BBL, 0x53B8_D9FE_50C2_BB0DL, + /* 289 */ 0x7CBD_71E8_6922_3792L, 0x52C1_5CCA_1AD1_2B48L, + /* 290 */ 0x63CA_C186_BA81_C60EL, 0x7567_7D6E_7BDA_8906L, + /* 291 */ 0x4FD5_679E_FB9B_04D8L, 0x5DEC_6458_6315_3A6CL, + /* 292 */ 0x7FBB_D8FE_5F5E_6E27L, 0x497A_3A27_04EE_C3DFL, + }; +} diff -Nru rhino-1.7.15/src/org/mozilla/javascript/v8dtoa/CachedPowers.java rhino-1.7.15.1/src/org/mozilla/javascript/v8dtoa/CachedPowers.java --- rhino-1.7.15/src/org/mozilla/javascript/v8dtoa/CachedPowers.java 2024-05-04 00:41:43.000000000 +0000 +++ rhino-1.7.15.1/src/org/mozilla/javascript/v8dtoa/CachedPowers.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,157 +0,0 @@ -// Copyright 2010 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Ported to Java from Mozilla's version of V8-dtoa by Hannes Wallnoefer. -// The original revision was 67d1049b0bf9 from the mozilla-central tree. - -package org.mozilla.javascript.v8dtoa; - -public class CachedPowers { - - static final double kD_1_LOG2_10 = 0.30102999566398114; // 1 / lg(10) - - static class CachedPower { - long significand; - short binaryExponent; - short decimalExponent; - - CachedPower(long significand, short binaryExponent, short decimalExponent) { - this.significand = significand; - this.binaryExponent = binaryExponent; - this.decimalExponent = decimalExponent; - } - } - - static int getCachedPower(int e, int alpha, int gamma, DiyFp c_mk) { - int kQ = DiyFp.kSignificandSize; - double k = Math.ceil((alpha - e + kQ - 1) * kD_1_LOG2_10); - int index = (GRISU_CACHE_OFFSET + (int) k - 1) / CACHED_POWERS_SPACING + 1; - CachedPower cachedPower = CACHED_POWERS[index]; - - c_mk.setF(cachedPower.significand); - c_mk.setE(cachedPower.binaryExponent); - assert ((alpha <= c_mk.e() + e) && (c_mk.e() + e <= gamma)); - return cachedPower.decimalExponent; - } - - // Code below is converted from GRISU_CACHE_NAME(8) in file "powers-ten.h" - // Regexp to convert this from original C++ source: - // \{GRISU_UINT64_C\((\w+), (\w+)\), (\-?\d+), (\-?\d+)\} - - // interval between entries of the powers cache below - static final int CACHED_POWERS_SPACING = 8; - - static final CachedPower[] CACHED_POWERS = { - new CachedPower(0xe61acf033d1a45dfL, (short) -1087, (short) -308), - new CachedPower(0xab70fe17c79ac6caL, (short) -1060, (short) -300), - new CachedPower(0xff77b1fcbebcdc4fL, (short) -1034, (short) -292), - new CachedPower(0xbe5691ef416bd60cL, (short) -1007, (short) -284), - new CachedPower(0x8dd01fad907ffc3cL, (short) -980, (short) -276), - new CachedPower(0xd3515c2831559a83L, (short) -954, (short) -268), - new CachedPower(0x9d71ac8fada6c9b5L, (short) -927, (short) -260), - new CachedPower(0xea9c227723ee8bcbL, (short) -901, (short) -252), - new CachedPower(0xaecc49914078536dL, (short) -874, (short) -244), - new CachedPower(0x823c12795db6ce57L, (short) -847, (short) -236), - new CachedPower(0xc21094364dfb5637L, (short) -821, (short) -228), - new CachedPower(0x9096ea6f3848984fL, (short) -794, (short) -220), - new CachedPower(0xd77485cb25823ac7L, (short) -768, (short) -212), - new CachedPower(0xa086cfcd97bf97f4L, (short) -741, (short) -204), - new CachedPower(0xef340a98172aace5L, (short) -715, (short) -196), - new CachedPower(0xb23867fb2a35b28eL, (short) -688, (short) -188), - new CachedPower(0x84c8d4dfd2c63f3bL, (short) -661, (short) -180), - new CachedPower(0xc5dd44271ad3cdbaL, (short) -635, (short) -172), - new CachedPower(0x936b9fcebb25c996L, (short) -608, (short) -164), - new CachedPower(0xdbac6c247d62a584L, (short) -582, (short) -156), - new CachedPower(0xa3ab66580d5fdaf6L, (short) -555, (short) -148), - new CachedPower(0xf3e2f893dec3f126L, (short) -529, (short) -140), - new CachedPower(0xb5b5ada8aaff80b8L, (short) -502, (short) -132), - new CachedPower(0x87625f056c7c4a8bL, (short) -475, (short) -124), - new CachedPower(0xc9bcff6034c13053L, (short) -449, (short) -116), - new CachedPower(0x964e858c91ba2655L, (short) -422, (short) -108), - new CachedPower(0xdff9772470297ebdL, (short) -396, (short) -100), - new CachedPower(0xa6dfbd9fb8e5b88fL, (short) -369, (short) -92), - new CachedPower(0xf8a95fcf88747d94L, (short) -343, (short) -84), - new CachedPower(0xb94470938fa89bcfL, (short) -316, (short) -76), - new CachedPower(0x8a08f0f8bf0f156bL, (short) -289, (short) -68), - new CachedPower(0xcdb02555653131b6L, (short) -263, (short) -60), - new CachedPower(0x993fe2c6d07b7facL, (short) -236, (short) -52), - new CachedPower(0xe45c10c42a2b3b06L, (short) -210, (short) -44), - new CachedPower(0xaa242499697392d3L, (short) -183, (short) -36), - new CachedPower(0xfd87b5f28300ca0eL, (short) -157, (short) -28), - new CachedPower(0xbce5086492111aebL, (short) -130, (short) -20), - new CachedPower(0x8cbccc096f5088ccL, (short) -103, (short) -12), - new CachedPower(0xd1b71758e219652cL, (short) -77, (short) -4), - new CachedPower(0x9c40000000000000L, (short) -50, (short) 4), - new CachedPower(0xe8d4a51000000000L, (short) -24, (short) 12), - new CachedPower(0xad78ebc5ac620000L, (short) 3, (short) 20), - new CachedPower(0x813f3978f8940984L, (short) 30, (short) 28), - new CachedPower(0xc097ce7bc90715b3L, (short) 56, (short) 36), - new CachedPower(0x8f7e32ce7bea5c70L, (short) 83, (short) 44), - new CachedPower(0xd5d238a4abe98068L, (short) 109, (short) 52), - new CachedPower(0x9f4f2726179a2245L, (short) 136, (short) 60), - new CachedPower(0xed63a231d4c4fb27L, (short) 162, (short) 68), - new CachedPower(0xb0de65388cc8ada8L, (short) 189, (short) 76), - new CachedPower(0x83c7088e1aab65dbL, (short) 216, (short) 84), - new CachedPower(0xc45d1df942711d9aL, (short) 242, (short) 92), - new CachedPower(0x924d692ca61be758L, (short) 269, (short) 100), - new CachedPower(0xda01ee641a708deaL, (short) 295, (short) 108), - new CachedPower(0xa26da3999aef774aL, (short) 322, (short) 116), - new CachedPower(0xf209787bb47d6b85L, (short) 348, (short) 124), - new CachedPower(0xb454e4a179dd1877L, (short) 375, (short) 132), - new CachedPower(0x865b86925b9bc5c2L, (short) 402, (short) 140), - new CachedPower(0xc83553c5c8965d3dL, (short) 428, (short) 148), - new CachedPower(0x952ab45cfa97a0b3L, (short) 455, (short) 156), - new CachedPower(0xde469fbd99a05fe3L, (short) 481, (short) 164), - new CachedPower(0xa59bc234db398c25L, (short) 508, (short) 172), - new CachedPower(0xf6c69a72a3989f5cL, (short) 534, (short) 180), - new CachedPower(0xb7dcbf5354e9beceL, (short) 561, (short) 188), - new CachedPower(0x88fcf317f22241e2L, (short) 588, (short) 196), - new CachedPower(0xcc20ce9bd35c78a5L, (short) 614, (short) 204), - new CachedPower(0x98165af37b2153dfL, (short) 641, (short) 212), - new CachedPower(0xe2a0b5dc971f303aL, (short) 667, (short) 220), - new CachedPower(0xa8d9d1535ce3b396L, (short) 694, (short) 228), - new CachedPower(0xfb9b7cd9a4a7443cL, (short) 720, (short) 236), - new CachedPower(0xbb764c4ca7a44410L, (short) 747, (short) 244), - new CachedPower(0x8bab8eefb6409c1aL, (short) 774, (short) 252), - new CachedPower(0xd01fef10a657842cL, (short) 800, (short) 260), - new CachedPower(0x9b10a4e5e9913129L, (short) 827, (short) 268), - new CachedPower(0xe7109bfba19c0c9dL, (short) 853, (short) 276), - new CachedPower(0xac2820d9623bf429L, (short) 880, (short) 284), - new CachedPower(0x80444b5e7aa7cf85L, (short) 907, (short) 292), - new CachedPower(0xbf21e44003acdd2dL, (short) 933, (short) 300), - new CachedPower(0x8e679c2f5e44ff8fL, (short) 960, (short) 308), - new CachedPower(0xd433179d9c8cb841L, (short) 986, (short) 316), - new CachedPower(0x9e19db92b4e31ba9L, (short) 1013, (short) 324), - new CachedPower(0xeb96bf6ebadf77d9L, (short) 1039, (short) 332), - new CachedPower(0xaf87023b9bf0ee6bL, (short) 1066, (short) 340) - }; - - static final int GRISU_CACHE_MAX_DISTANCE = 27; - // nb elements (8): 82 - - static final int GRISU_CACHE_OFFSET = 308; -} diff -Nru rhino-1.7.15/src/org/mozilla/javascript/v8dtoa/DiyFp.java rhino-1.7.15.1/src/org/mozilla/javascript/v8dtoa/DiyFp.java --- rhino-1.7.15/src/org/mozilla/javascript/v8dtoa/DiyFp.java 2024-05-04 00:41:43.000000000 +0000 +++ rhino-1.7.15.1/src/org/mozilla/javascript/v8dtoa/DiyFp.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,157 +0,0 @@ -// Copyright 2010 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Ported to Java from Mozilla's version of V8-dtoa by Hannes Wallnoefer. -// The original revision was 67d1049b0bf9 from the mozilla-central tree. - -package org.mozilla.javascript.v8dtoa; - -// This "Do It Yourself Floating Point" class implements a floating-point number -// with a uint64 significand and an int exponent. Normalized DiyFp numbers will -// have the most significant bit of the significand set. -// Multiplication and Subtraction do not normalize their results. -// DiyFp are not designed to contain special doubles (NaN and Infinity). -class DiyFp { - - private long f; - private int e; - - static final int kSignificandSize = 64; - static final long kUint64MSB = 0x8000000000000000L; - - DiyFp() { - this.f = 0; - this.e = 0; - } - - DiyFp(long f, int e) { - this.f = f; - this.e = e; - } - - private static boolean uint64_gte(long a, long b) { - // greater-or-equal for unsigned int64 in java-style... - return (a == b) || ((a > b) ^ (a < 0) ^ (b < 0)); - } - - // this = this - other. - // The exponents of both numbers must be the same and the significand of this - // must be bigger than the significand of other. - // The result will not be normalized. - void subtract(DiyFp other) { - assert (e == other.e); - assert uint64_gte(f, other.f); - f -= other.f; - } - - // Returns a - b. - // The exponents of both numbers must be the same and this must be bigger - // than other. The result will not be normalized. - static DiyFp minus(DiyFp a, DiyFp b) { - DiyFp result = new DiyFp(a.f, a.e); - result.subtract(b); - return result; - } - - // this = this * other. - void multiply(DiyFp other) { - // Simply "emulates" a 128 bit multiplication. - // However: the resulting number only contains 64 bits. The least - // significant 64 bits are only used for rounding the most significant 64 - // bits. - final long kM32 = 0xFFFFFFFFL; - long a = f >>> 32; - long b = f & kM32; - long c = other.f >>> 32; - long d = other.f & kM32; - long ac = a * c; - long bc = b * c; - long ad = a * d; - long bd = b * d; - long tmp = (bd >>> 32) + (ad & kM32) + (bc & kM32); - // By adding 1U << 31 to tmp we round the final result. - // Halfway cases will be round up. - tmp += 1L << 31; - long result_f = ac + (ad >>> 32) + (bc >>> 32) + (tmp >>> 32); - e += other.e + 64; - f = result_f; - } - - // returns a * b; - static DiyFp times(DiyFp a, DiyFp b) { - DiyFp result = new DiyFp(a.f, a.e); - result.multiply(b); - return result; - } - - void normalize() { - assert (f != 0); - long f = this.f; - int e = this.e; - - // This method is mainly called for normalizing boundaries. In general - // boundaries need to be shifted by 10 bits. We thus optimize for this case. - final long k10MSBits = 0xFFC00000L << 32; - while ((f & k10MSBits) == 0) { - f <<= 10; - e -= 10; - } - while ((f & kUint64MSB) == 0) { - f <<= 1; - e--; - } - this.f = f; - this.e = e; - } - - static DiyFp normalize(DiyFp a) { - DiyFp result = new DiyFp(a.f, a.e); - result.normalize(); - return result; - } - - long f() { - return f; - } - - int e() { - return e; - } - - void setF(long new_value) { - f = new_value; - } - - void setE(int new_value) { - e = new_value; - } - - @Override - public String toString() { - return "[DiyFp f:" + f + ", e:" + e + "]"; - } -} diff -Nru rhino-1.7.15/src/org/mozilla/javascript/v8dtoa/DoubleHelper.java rhino-1.7.15.1/src/org/mozilla/javascript/v8dtoa/DoubleHelper.java --- rhino-1.7.15/src/org/mozilla/javascript/v8dtoa/DoubleHelper.java 2024-05-04 00:41:43.000000000 +0000 +++ rhino-1.7.15.1/src/org/mozilla/javascript/v8dtoa/DoubleHelper.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,131 +0,0 @@ -// Copyright 2010 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Ported to Java from Mozilla's version of V8-dtoa by Hannes Wallnoefer. -// The original revision was 67d1049b0bf9 from the mozilla-central tree. - -package org.mozilla.javascript.v8dtoa; - -// Helper functions for doubles. -public class DoubleHelper { - - static final long kSignMask = 0x8000000000000000L; - static final long kExponentMask = 0x7FF0000000000000L; - static final long kSignificandMask = 0x000FFFFFFFFFFFFFL; - static final long kHiddenBit = 0x0010000000000000L; - - static DiyFp asDiyFp(long d64) { - assert (!isSpecial(d64)); - return new DiyFp(significand(d64), exponent(d64)); - } - - // this->Significand() must not be 0. - static DiyFp asNormalizedDiyFp(long d64) { - long f = significand(d64); - int e = exponent(d64); - - assert (f != 0); - - // The current double could be a denormal. - while ((f & kHiddenBit) == 0) { - f <<= 1; - e--; - } - // Do the final shifts in one go. Don't forget the hidden bit (the '-1'). - f <<= DiyFp.kSignificandSize - kSignificandSize - 1; - e -= DiyFp.kSignificandSize - kSignificandSize - 1; - return new DiyFp(f, e); - } - - static int exponent(long d64) { - if (isDenormal(d64)) return kDenormalExponent; - - int biased_e = (int) (((d64 & kExponentMask) >>> kSignificandSize) & 0xffffffffL); - return biased_e - kExponentBias; - } - - static long significand(long d64) { - long significand = d64 & kSignificandMask; - if (!isDenormal(d64)) { - return significand + kHiddenBit; - } - return significand; - } - - // Returns true if the double is a denormal. - static boolean isDenormal(long d64) { - return (d64 & kExponentMask) == 0L; - } - - // We consider denormals not to be special. - // Hence only Infinity and NaN are special. - static boolean isSpecial(long d64) { - return (d64 & kExponentMask) == kExponentMask; - } - - static boolean isNan(long d64) { - return ((d64 & kExponentMask) == kExponentMask) && ((d64 & kSignificandMask) != 0L); - } - - static boolean isInfinite(long d64) { - return ((d64 & kExponentMask) == kExponentMask) && ((d64 & kSignificandMask) == 0L); - } - - static int sign(long d64) { - return (d64 & kSignMask) == 0L ? 1 : -1; - } - - // Returns the two boundaries of first argument. - // The bigger boundary (m_plus) is normalized. The lower boundary has the same - // exponent as m_plus. - static void normalizedBoundaries(long d64, DiyFp m_minus, DiyFp m_plus) { - DiyFp v = asDiyFp(d64); - boolean significand_is_zero = (v.f() == kHiddenBit); - m_plus.setF((v.f() << 1) + 1); - m_plus.setE(v.e() - 1); - m_plus.normalize(); - if (significand_is_zero && v.e() != kDenormalExponent) { - // The boundary is closer. Think of v = 1000e10 and v- = 9999e9. - // Then the boundary (== (v - v-)/2) is not just at a distance of 1e9 but - // at a distance of 1e8. - // The only exception is for the smallest normal: the largest denormal is - // at the same distance as its successor. - // Note: denormals have the same exponent as the smallest normals. - m_minus.setF((v.f() << 2) - 1); - m_minus.setE(v.e() - 2); - } else { - m_minus.setF((v.f() << 1) - 1); - m_minus.setE(v.e() - 1); - } - m_minus.setF(m_minus.f() << (m_minus.e() - m_plus.e())); - m_minus.setE(m_plus.e()); - } - - private static final int kSignificandSize = 52; // Excludes the hidden bit. - private static final int kExponentBias = 0x3FF + kSignificandSize; - private static final int kDenormalExponent = -kExponentBias + 1; -} diff -Nru rhino-1.7.15/src/org/mozilla/javascript/v8dtoa/FastDtoa.java rhino-1.7.15.1/src/org/mozilla/javascript/v8dtoa/FastDtoa.java --- rhino-1.7.15/src/org/mozilla/javascript/v8dtoa/FastDtoa.java 2024-05-04 00:41:43.000000000 +0000 +++ rhino-1.7.15.1/src/org/mozilla/javascript/v8dtoa/FastDtoa.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,509 +0,0 @@ -// Copyright 2010 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Ported to Java from Mozilla's version of V8-dtoa by Hannes Wallnoefer. -// The original revision was 67d1049b0bf9 from the mozilla-central tree. - -package org.mozilla.javascript.v8dtoa; - -public class FastDtoa { - - // FastDtoa will produce at most kFastDtoaMaximalLength digits. - static final int kFastDtoaMaximalLength = 17; - - // The minimal and maximal target exponent define the range of w's binary - // exponent, where 'w' is the result of multiplying the input by a cached power - // of ten. - // - // A different range might be chosen on a different platform, to optimize digit - // generation, but a smaller range requires more powers of ten to be cached. - static final int minimal_target_exponent = -60; - static final int maximal_target_exponent = -32; - - // Adjusts the last digit of the generated number, and screens out generated - // solutions that may be inaccurate. A solution may be inaccurate if it is - // outside the safe interval, or if we ctannot prove that it is closer to the - // input than a neighboring representation of the same length. - // - // Input: * buffer containing the digits of too_high / 10^kappa - // * distance_too_high_w == (too_high - w).f() * unit - // * unsafe_interval == (too_high - too_low).f() * unit - // * rest = (too_high - buffer * 10^kappa).f() * unit - // * ten_kappa = 10^kappa * unit - // * unit = the common multiplier - // Output: returns true if the buffer is guaranteed to contain the closest - // representable number to the input. - // Modifies the generated digits in the buffer to approach (round towards) w. - static boolean roundWeed( - FastDtoaBuilder buffer, - long distance_too_high_w, - long unsafe_interval, - long rest, - long ten_kappa, - long unit) { - long small_distance = distance_too_high_w - unit; - long big_distance = distance_too_high_w + unit; - // Let w_low = too_high - big_distance, and - // w_high = too_high - small_distance. - // Note: w_low < w < w_high - // - // The real w (* unit) must lie somewhere inside the interval - // ]w_low; w_low[ (often written as "(w_low; w_low)") - - // Basically the buffer currently contains a number in the unsafe interval - // ]too_low; too_high[ with too_low < w < too_high - // - // too_high - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // ^v 1 unit ^ ^ ^ ^ - // boundary_high --------------------- . . . . - // ^v 1 unit . . . . - // - - - - - - - - - - - - - - - - - - - + - - + - - - - - - . . - // . . ^ . . - // . big_distance . . . - // . . . . rest - // small_distance . . . . - // v . . . . - // w_high - - - - - - - - - - - - - - - - - - . . . . - // ^v 1 unit . . . . - // w ---------------------------------------- . . . . - // ^v 1 unit v . . . - // w_low - - - - - - - - - - - - - - - - - - - - - . . . - // . . v - // buffer --------------------------------------------------+-------+-------- - // . . - // safe_interval . - // v . - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - . - // ^v 1 unit . - // boundary_low ------------------------- unsafe_interval - // ^v 1 unit v - // too_low - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - // - // Note that the value of buffer could lie anywhere inside the range too_low - // to too_high. - // - // boundary_low, boundary_high and w are approximations of the real boundaries - // and v (the input number). They are guaranteed to be precise up to one unit. - // In fact the error is guaranteed to be strictly less than one unit. - // - // Anything that lies outside the unsafe interval is guaranteed not to round - // to v when read again. - // Anything that lies inside the safe interval is guaranteed to round to v - // when read again. - // If the number inside the buffer lies inside the unsafe interval but not - // inside the safe interval then we simply do not know and bail out (returning - // false). - // - // Similarly we have to take into account the imprecision of 'w' when rounding - // the buffer. If we have two potential representations we need to make sure - // that the chosen one is closer to w_low and w_high since v can be anywhere - // between them. - // - // By generating the digits of too_high we got the largest (closest to - // too_high) buffer that is still in the unsafe interval. In the case where - // w_high < buffer < too_high we try to decrement the buffer. - // This way the buffer approaches (rounds towards) w. - // There are 3 conditions that stop the decrementation process: - // 1) the buffer is already below w_high - // 2) decrementing the buffer would make it leave the unsafe interval - // 3) decrementing the buffer would yield a number below w_high and farther - // away than the current number. In other words: - // (buffer{-1} < w_high) && w_high - buffer{-1} > buffer - w_high - // Instead of using the buffer directly we use its distance to too_high. - // Conceptually rest ~= too_high - buffer - while (rest < small_distance - && // Negated condition 1 - unsafe_interval - rest >= ten_kappa - && // Negated condition 2 - (rest + ten_kappa < small_distance - || // buffer{-1} > w_high - small_distance - rest >= rest + ten_kappa - small_distance)) { - buffer.decreaseLast(); - rest += ten_kappa; - } - - // We have approached w+ as much as possible. We now test if approaching w- - // would require changing the buffer. If yes, then we have two possible - // representations close to w, but we cannot decide which one is closer. - if (rest < big_distance - && unsafe_interval - rest >= ten_kappa - && (rest + ten_kappa < big_distance - || big_distance - rest > rest + ten_kappa - big_distance)) { - return false; - } - - // Weeding test. - // The safe interval is [too_low + 2 ulp; too_high - 2 ulp] - // Since too_low = too_high - unsafe_interval this is equivalent to - // [too_high - unsafe_interval + 4 ulp; too_high - 2 ulp] - // Conceptually we have: rest ~= too_high - buffer - return (2 * unit <= rest) && (rest <= unsafe_interval - 4 * unit); - } - - static final int kTen4 = 10000; - static final int kTen5 = 100000; - static final int kTen6 = 1000000; - static final int kTen7 = 10000000; - static final int kTen8 = 100000000; - static final int kTen9 = 1000000000; - - // Returns the biggest power of ten that is less than or equal than the given - // number. We furthermore receive the maximum number of bits 'number' has. - // If number_bits == 0 then 0^-1 is returned - // The number of bits must be <= 32. - // Precondition: (1 << number_bits) <= number < (1 << (number_bits + 1)). - static long biggestPowerTen(int number, int number_bits) { - int power, exponent; - switch (number_bits) { - case 32: - case 31: - case 30: - if (kTen9 <= number) { - power = kTen9; - exponent = 9; - break; - } // else fallthrough - case 29: - case 28: - case 27: - if (kTen8 <= number) { - power = kTen8; - exponent = 8; - break; - } // else fallthrough - case 26: - case 25: - case 24: - if (kTen7 <= number) { - power = kTen7; - exponent = 7; - break; - } // else fallthrough - case 23: - case 22: - case 21: - case 20: - if (kTen6 <= number) { - power = kTen6; - exponent = 6; - break; - } // else fallthrough - case 19: - case 18: - case 17: - if (kTen5 <= number) { - power = kTen5; - exponent = 5; - break; - } // else fallthrough - case 16: - case 15: - case 14: - if (kTen4 <= number) { - power = kTen4; - exponent = 4; - break; - } // else fallthrough - case 13: - case 12: - case 11: - case 10: - if (1000 <= number) { - power = 1000; - exponent = 3; - break; - } // else fallthrough - case 9: - case 8: - case 7: - if (100 <= number) { - power = 100; - exponent = 2; - break; - } // else fallthrough - case 6: - case 5: - case 4: - if (10 <= number) { - power = 10; - exponent = 1; - break; - } // else fallthrough - case 3: - case 2: - case 1: - if (1 <= number) { - power = 1; - exponent = 0; - break; - } // else fallthrough - case 0: - power = 0; - exponent = -1; - break; - default: - // Following assignments are here to silence compiler warnings. - power = 0; - exponent = 0; - // UNREACHABLE(); - } - return ((long) power << 32) | (0xffffffffL & exponent); - } - - private static boolean uint64_lte(long a, long b) { - // less-or-equal for unsigned int64 in java-style... - return (a == b) || ((a < b) ^ (a < 0) ^ (b < 0)); - } - - // Generates the digits of input number w. - // w is a floating-point number (DiyFp), consisting of a significand and an - // exponent. Its exponent is bounded by minimal_target_exponent and - // maximal_target_exponent. - // Hence -60 <= w.e() <= -32. - // - // Returns false if it fails, in which case the generated digits in the buffer - // should not be used. - // Preconditions: - // * low, w and high are correct up to 1 ulp (unit in the last place). That - // is, their error must be less that a unit of their last digits. - // * low.e() == w.e() == high.e() - // * low < w < high, and taking into account their error: low~ <= high~ - // * minimal_target_exponent <= w.e() <= maximal_target_exponent - // Postconditions: returns false if procedure fails. - // otherwise: - // * buffer is not null-terminated, but len contains the number of digits. - // * buffer contains the shortest possible decimal digit-sequence - // such that LOW < buffer * 10^kappa < HIGH, where LOW and HIGH are the - // correct values of low and high (without their error). - // * if more than one decimal representation gives the minimal number of - // decimal digits then the one closest to W (where W is the correct value - // of w) is chosen. - // Remark: this procedure takes into account the imprecision of its input - // numbers. If the precision is not enough to guarantee all the postconditions - // then false is returned. This usually happens rarely (~0.5%). - // - // Say, for the sake of example, that - // w.e() == -48, and w.f() == 0x1234567890abcdef - // w's value can be computed by w.f() * 2^w.e() - // We can obtain w's integral digits by simply shifting w.f() by -w.e(). - // -> w's integral part is 0x1234 - // w's fractional part is therefore 0x567890abcdef. - // Printing w's integral part is easy (simply print 0x1234 in decimal). - // In order to print its fraction we repeatedly multiply the fraction by 10 and - // get each digit. Example the first digit after the point would be computed by - // (0x567890abcdef * 10) >> 48. -> 3 - // The whole thing becomes slightly more complicated because we want to stop - // once we have enough digits. That is, once the digits inside the buffer - // represent 'w' we can stop. Everything inside the interval low - high - // represents w. However we have to pay attention to low, high and w's - // imprecision. - static boolean digitGen(DiyFp low, DiyFp w, DiyFp high, FastDtoaBuilder buffer, int mk) { - assert (low.e() == w.e() && w.e() == high.e()); - assert uint64_lte(low.f() + 1, high.f() - 1); - assert (minimal_target_exponent <= w.e() && w.e() <= maximal_target_exponent); - // low, w and high are imprecise, but by less than one ulp (unit in the last - // place). - // If we remove (resp. add) 1 ulp from low (resp. high) we are certain that - // the new numbers are outside of the interval we want the final - // representation to lie in. - // Inversely adding (resp. removing) 1 ulp from low (resp. high) would yield - // numbers that are certain to lie in the interval. We will use this fact - // later on. - // We will now start by generating the digits within the uncertain - // interval. Later we will weed out representations that lie outside the safe - // interval and thus _might_ lie outside the correct interval. - long unit = 1; - DiyFp too_low = new DiyFp(low.f() - unit, low.e()); - DiyFp too_high = new DiyFp(high.f() + unit, high.e()); - // too_low and too_high are guaranteed to lie outside the interval we want the - // generated number in. - DiyFp unsafe_interval = DiyFp.minus(too_high, too_low); - // We now cut the input number into two parts: the integral digits and the - // fractionals. We will not write any decimal separator though, but adapt - // kappa instead. - // Reminder: we are currently computing the digits (stored inside the buffer) - // such that: too_low < buffer * 10^kappa < too_high - // We use too_high for the digit_generation and stop as soon as possible. - // If we stop early we effectively round down. - DiyFp one = new DiyFp(1L << -w.e(), w.e()); - // Division by one is a shift. - int integrals = (int) ((too_high.f() >>> -one.e()) & 0xffffffffL); - // Modulo by one is an and. - long fractionals = too_high.f() & (one.f() - 1); - long result = biggestPowerTen(integrals, DiyFp.kSignificandSize - (-one.e())); - int divider = (int) ((result >>> 32) & 0xffffffffL); - int divider_exponent = (int) (result & 0xffffffffL); - int kappa = divider_exponent + 1; - // Loop invariant: buffer = too_high / 10^kappa (integer division) - // The invariant holds for the first iteration: kappa has been initialized - // with the divider exponent + 1. And the divider is the biggest power of ten - // that is smaller than integrals. - while (kappa > 0) { - int digit = integrals / divider; - buffer.append((char) ('0' + digit)); - integrals %= divider; - kappa--; - // Note that kappa now equals the exponent of the divider and that the - // invariant thus holds again. - long rest = ((long) integrals << -one.e()) + fractionals; - // Invariant: too_high = buffer * 10^kappa + DiyFp(rest, one.e()) - // Reminder: unsafe_interval.e() == one.e() - if (rest < unsafe_interval.f()) { - // Rounding down (by not emitting the remaining digits) yields a number - // that lies within the unsafe interval. - buffer.point = buffer.end - mk + kappa; - return roundWeed( - buffer, - DiyFp.minus(too_high, w).f(), - unsafe_interval.f(), - rest, - (long) divider << -one.e(), - unit); - } - divider /= 10; - } - - // The integrals have been generated. We are at the point of the decimal - // separator. In the following loop we simply multiply the remaining digits by - // 10 and divide by one. We just need to pay attention to multiply associated - // data (like the interval or 'unit'), too. - // Instead of multiplying by 10 we multiply by 5 (cheaper operation) and - // increase its (imaginary) exponent. At the same time we decrease the - // divider's (one's) exponent and shift its significand. - // Basically, if fractionals was a DiyFp (with fractionals.e == one.e): - // fractionals.f *= 10; - // fractionals.f >>= 1; fractionals.e++; // value remains unchanged. - // one.f >>= 1; one.e++; // value remains unchanged. - // and we have again fractionals.e == one.e which allows us to divide - // fractionals.f() by one.f() - // We simply combine the *= 10 and the >>= 1. - while (true) { - fractionals *= 5; - unit *= 5; - unsafe_interval.setF(unsafe_interval.f() * 5); - unsafe_interval.setE(unsafe_interval.e() + 1); // Will be optimized out. - one.setF(one.f() >>> 1); - one.setE(one.e() + 1); - // Integer division by one. - int digit = (int) ((fractionals >>> -one.e()) & 0xffffffffL); - buffer.append((char) ('0' + digit)); - fractionals &= one.f() - 1; // Modulo by one. - kappa--; - if (fractionals < unsafe_interval.f()) { - buffer.point = buffer.end - mk + kappa; - return roundWeed( - buffer, - DiyFp.minus(too_high, w).f() * unit, - unsafe_interval.f(), - fractionals, - one.f(), - unit); - } - } - } - - // Provides a decimal representation of v. - // Returns true if it succeeds, otherwise the result cannot be trusted. - // There will be *length digits inside the buffer (not null-terminated). - // If the function returns true then - // v == (double) (buffer * 10^decimal_exponent). - // The digits in the buffer are the shortest representation possible: no - // 0.09999999999999999 instead of 0.1. The shorter representation will even be - // chosen even if the longer one would be closer to v. - // The last digit will be closest to the actual v. That is, even if several - // digits might correctly yield 'v' when read again, the closest will be - // computed. - static boolean grisu3(double v, FastDtoaBuilder buffer) { - long bits = Double.doubleToLongBits(v); - DiyFp w = DoubleHelper.asNormalizedDiyFp(bits); - // boundary_minus and boundary_plus are the boundaries between v and its - // closest floating-point neighbors. Any number strictly between - // boundary_minus and boundary_plus will round to v when convert to a double. - // Grisu3 will never output representations that lie exactly on a boundary. - DiyFp boundary_minus = new DiyFp(), boundary_plus = new DiyFp(); - DoubleHelper.normalizedBoundaries(bits, boundary_minus, boundary_plus); - assert (boundary_plus.e() == w.e()); - DiyFp ten_mk = new DiyFp(); // Cached power of ten: 10^-k - int mk = - CachedPowers.getCachedPower( - w.e() + DiyFp.kSignificandSize, - minimal_target_exponent, - maximal_target_exponent, - ten_mk); - assert (minimal_target_exponent <= w.e() + ten_mk.e() + DiyFp.kSignificandSize - && maximal_target_exponent >= w.e() + ten_mk.e() + DiyFp.kSignificandSize); - // Note that ten_mk is only an approximation of 10^-k. A DiyFp only contains a - // 64 bit significand and ten_mk is thus only precise up to 64 bits. - - // The DiyFp::Times procedure rounds its result, and ten_mk is approximated - // too. The variable scaled_w (as well as scaled_boundary_minus/plus) are now - // off by a small amount. - // In fact: scaled_w - w*10^k < 1ulp (unit in the last place) of scaled_w. - // In other words: let f = scaled_w.f() and e = scaled_w.e(), then - // (f-1) * 2^e < w*10^k < (f+1) * 2^e - DiyFp scaled_w = DiyFp.times(w, ten_mk); - assert (scaled_w.e() == boundary_plus.e() + ten_mk.e() + DiyFp.kSignificandSize); - // In theory it would be possible to avoid some recomputations by computing - // the difference between w and boundary_minus/plus (a power of 2) and to - // compute scaled_boundary_minus/plus by subtracting/adding from - // scaled_w. However the code becomes much less readable and the speed - // enhancements are not terriffic. - DiyFp scaled_boundary_minus = DiyFp.times(boundary_minus, ten_mk); - DiyFp scaled_boundary_plus = DiyFp.times(boundary_plus, ten_mk); - - // DigitGen will generate the digits of scaled_w. Therefore we have - // v == (double) (scaled_w * 10^-mk). - // Set decimal_exponent == -mk and pass it to DigitGen. If scaled_w is not an - // integer than it will be updated. For instance if scaled_w == 1.23 then - // the buffer will be filled with "123" und the decimal_exponent will be - // decreased by 2. - return digitGen(scaled_boundary_minus, scaled_w, scaled_boundary_plus, buffer, mk); - } - - public static boolean dtoa(double v, FastDtoaBuilder buffer) { - assert (v > 0); - assert (!Double.isNaN(v)); - assert (!Double.isInfinite(v)); - - return grisu3(v, buffer); - } - - public static String numberToString(double v) { - FastDtoaBuilder buffer = new FastDtoaBuilder(); - return numberToString(v, buffer) ? buffer.format() : null; - } - - public static boolean numberToString(double v, FastDtoaBuilder buffer) { - buffer.reset(); - if (v < 0) { - buffer.append('-'); - v = -v; - } - return dtoa(v, buffer); - } -} diff -Nru rhino-1.7.15/src/org/mozilla/javascript/v8dtoa/FastDtoaBuilder.java rhino-1.7.15.1/src/org/mozilla/javascript/v8dtoa/FastDtoaBuilder.java --- rhino-1.7.15/src/org/mozilla/javascript/v8dtoa/FastDtoaBuilder.java 2024-05-04 00:41:43.000000000 +0000 +++ rhino-1.7.15.1/src/org/mozilla/javascript/v8dtoa/FastDtoaBuilder.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,108 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.javascript.v8dtoa; - -import java.util.Arrays; - -public class FastDtoaBuilder { - - // allocate buffer for generated digits + extra notation + padding zeroes - final char[] chars = new char[FastDtoa.kFastDtoaMaximalLength + 8]; - int end = 0; - int point; - boolean formatted = false; - - void append(char c) { - chars[end++] = c; - } - - void decreaseLast() { - chars[end - 1]--; - } - - public void reset() { - end = 0; - formatted = false; - } - - @Override - public String toString() { - return "[chars:" + new String(chars, 0, end) + ", point:" + point + "]"; - } - - public String format() { - if (!formatted) { - // check for minus sign - int firstDigit = chars[0] == '-' ? 1 : 0; - int decPoint = point - firstDigit; - if (decPoint < -5 || decPoint > 21) { - toExponentialFormat(firstDigit, decPoint); - } else { - toFixedFormat(firstDigit, decPoint); - } - formatted = true; - } - return new String(chars, 0, end); - } - - private void toFixedFormat(int firstDigit, int decPoint) { - if (point < end) { - // insert decimal point - if (decPoint > 0) { - // >= 1, split decimals and insert point - System.arraycopy(chars, point, chars, point + 1, end - point); - chars[point] = '.'; - end++; - } else { - // < 1, - int target = firstDigit + 2 - decPoint; - System.arraycopy(chars, firstDigit, chars, target, end - firstDigit); - chars[firstDigit] = '0'; - chars[firstDigit + 1] = '.'; - if (decPoint < 0) { - Arrays.fill(chars, firstDigit + 2, target, '0'); - } - end += 2 - decPoint; - } - } else if (point > end) { - // large integer, add trailing zeroes - Arrays.fill(chars, end, point, '0'); - end += point - end; - } - } - - private void toExponentialFormat(int firstDigit, int decPoint) { - if (end - firstDigit > 1) { - // insert decimal point if more than one digit was produced - int dot = firstDigit + 1; - System.arraycopy(chars, dot, chars, dot + 1, end - dot); - chars[dot] = '.'; - end++; - } - chars[end++] = 'e'; - char sign = '+'; - int exp = decPoint - 1; - if (exp < 0) { - sign = '-'; - exp = -exp; - } - chars[end++] = sign; - - int charPos = exp > 99 ? end + 2 : exp > 9 ? end + 1 : end; - end = charPos + 1; - - // code below is needed because Integer.getChars() is not public - for (; ; ) { - int r = exp % 10; - chars[charPos--] = digits[r]; - exp = exp / 10; - if (exp == 0) break; - } - } - - static final char[] digits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; -} diff -Nru rhino-1.7.15/testsrc/org/mozilla/javascript/tests/NumberToStringTest.java rhino-1.7.15.1/testsrc/org/mozilla/javascript/tests/NumberToStringTest.java --- rhino-1.7.15/testsrc/org/mozilla/javascript/tests/NumberToStringTest.java 1970-01-01 00:00:00.000000000 +0000 +++ rhino-1.7.15.1/testsrc/org/mozilla/javascript/tests/NumberToStringTest.java 2025-12-03 03:43:04.000000000 +0000 @@ -0,0 +1,89 @@ +package org.mozilla.javascript.tests; + +import static org.junit.Assert.assertEquals; + +import java.util.Collection; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.mozilla.javascript.ScriptRuntime; + +@RunWith(Parameterized.class) +public class NumberToStringTest { + @Parameterized.Parameter(0) + public String expected; + + @Parameterized.Parameter(1) + public double value; + + // toString results from V8 compared to their inputs + private static final Object[][] TO_STRING_TESTS = { + // order: expected result, source + {"0", 0.0}, + {"1", 1.0}, + {"-1", -1.0}, + {"100", 100}, + {"0.000001", 0.000001}, + {"0.9999", 0.9999}, + {"123.456", 123.456}, + {"-123.456", -123.456}, + {"1e+23", 1E23}, + {"1.0000000000000001e+23", 100000000000000000000001.0}, + {"3.14", 3.14}, + {"1000000000", 1E9}, + {"1e+31", 1E31}, + // Make sure we have various high and low ranges + {"3.141592653589793", Math.PI}, + {"314159265358.9793", Math.PI * 100000000000.0}, + {"3.141592653589793e-11", Math.PI / 100000000000.0}, + {"3141592653589793000", Math.PI * 1000000000000000.0 * 1000.0}, + {"3.1415926535897934e-14", 3.1415926535897934E-14}, + {"3.141592653589793e+23", Math.PI * 1000000000000000.0 * 100000000.0}, + {"9.352546905515962e+198", 9.3525469055159624998555744E198}, + // Boundaries + {"1e-7", 1E-7}, + {"1e+21", 1E21}, + {"1e+21", 1.00000000000000001E21}, + {"1e+21", 0.99999999999999999E21}, + {"1.0000000000000001e+21", 1.0000000000000001E21}, + {"999999999999999900000", 0.9999999999999999E21}, + {"1e-7", 1.00000000000000001E-7}, + {"1.0000000000000001e-7", 1.0000000000000001E-7}, + {"1e-7", 0.9999999999999999E-7}, + {"9.99999999999999e-8", 0.999999999999999E-7}, + // Denormals + {"5.88e-39", 5.88E-39}, + {"4.47118444e-314", 4.47118444E-314}, + // Specific values from the JDK test suite + {"282879384806159000", 2.82879384806159E17}, + {"1387364135037754000", 1.387364135037754E18}, + {"145800632428665000", 1.45800632428665E17}, + {"1.6e-322", 1.6E-322}, + {"6.3e-322", 6.3E-322}, + {"738790000000000000000", 7.3879E20}, + {"2e+23", 2.0E23}, + {"7e+22", 7.0E22}, + {"9.2e+22", 9.2E22}, + {"9.5e+21", 9.5E21}, + {"3.1e+22", 3.1E22}, + {"5.63e+21", 5.63E21}, + {"8.41e+21", 8.41E21}, + {"1.9400994884341945e+25", 1.9400994884341945E25}, + {"3.6131332396758635e+25", 3.6131332396758635E25}, + {"2.5138990223946153e+25", 2.5138990223946153E25}, + // These are controversial -- Java gives a more rounded- + // off result but the original Schubfach code does not. + {"9.9e-324", 9.9E-324}, + {"9.9e-323", 9.9E-323} + }; + + @Parameterized.Parameters() + public static Collection data() { + return java.util.Arrays.asList(TO_STRING_TESTS); + } + + @Test + public void testToString() { + assertEquals(expected, ScriptRuntime.toString(value)); + } +} diff -Nru rhino-1.7.15/testsrc/test262.properties rhino-1.7.15.1/testsrc/test262.properties --- rhino-1.7.15/testsrc/test262.properties 2024-05-04 00:41:43.000000000 +0000 +++ rhino-1.7.15.1/testsrc/test262.properties 2025-12-03 03:43:04.000000000 +0000 @@ -730,11 +730,7 @@ URIError/proto-from-ctor-realm.js {unsupported: [Reflect]} built-ins/Number 9/283 (3.18%) - prototype/toExponential/return-abrupt-tointeger-fractiondigits.js - prototype/toExponential/return-abrupt-tointeger-fractiondigits-symbol.js - prototype/toExponential/undefined-fractiondigits.js prototype/toLocaleString/length.js - prototype/toPrecision/nan.js proto-from-ctor-realm.js {unsupported: [Reflect]} S9.3.1_A2_U180E.js {unsupported: [u180e]} S9.3.1_A3_T1_U180E.js {unsupported: [u180e]}