8227391: Update double-conversion to version 3.1.5

Reviewed-by: attila
This commit is contained in:
Hannes Wallnöfer 2019-07-11 17:11:54 +02:00
parent 60b005d766
commit cd18508b2f
6 changed files with 36 additions and 19 deletions
src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/doubleconv
test/nashorn/src/jdk/nashorn/internal/runtime/doubleconv/test

@ -76,13 +76,10 @@ class Bignum {
// grow. There are no checks if the stack-allocated space is sufficient. // grow. There are no checks if the stack-allocated space is sufficient.
static final int kBigitCapacity = kMaxSignificantBits / kBigitSize; static final int kBigitCapacity = kMaxSignificantBits / kBigitSize;
private final int[] bigits_ = new int[kBigitCapacity];
// A vector backed by bigits_buffer_. This way accesses to the array are
// checked for out-of-bounds errors.
// Vector<int> bigits_;
private int used_digits_; private int used_digits_;
// The Bignum's value equals value(bigits_) * 2^(exponent_ * kBigitSize). // The Bignum's value equals value(bigits_) * 2^(exponent_ * kBigitSize).
private int exponent_; private int exponent_;
private final int[] bigits_ = new int[kBigitCapacity];
Bignum() {} Bignum() {}
@ -124,7 +121,9 @@ class Bignum {
void assignUInt16(final char value) { void assignUInt16(final char value) {
assert (kBigitSize >= 16); assert (kBigitSize >= 16);
zero(); zero();
if (value == 0) return; if (value == 0) {
return;
}
ensureCapacity(1); ensureCapacity(1);
bigits_[0] = value; bigits_[0] = value;
@ -136,7 +135,9 @@ class Bignum {
final int kUInt64Size = 64; final int kUInt64Size = 64;
zero(); zero();
if (value == 0) return; if (value == 0) {
return;
}
final int needed_bigits = kUInt64Size / kBigitSize + 1; final int needed_bigits = kUInt64Size / kBigitSize + 1;
ensureCapacity(needed_bigits); ensureCapacity(needed_bigits);
@ -521,26 +522,27 @@ class Bignum {
mask >>>= 2; mask >>>= 2;
long this_value = base; long this_value = base;
boolean delayed_multipliciation = false; boolean delayed_multiplication = false;
final long max_32bits = 0xFFFFFFFFL; final long max_32bits = 0xFFFFFFFFL;
while (mask != 0 && this_value <= max_32bits) { while (mask != 0 && this_value <= max_32bits) {
this_value = this_value * this_value; this_value = this_value * this_value;
// Verify that there is enough space in this_value to perform the // Verify that there is enough space in this_value to perform the
// multiplication. The first bit_size bits must be 0. // multiplication. The first bit_size bits must be 0.
if ((power_exponent & mask) != 0) { if ((power_exponent & mask) != 0) {
assert bit_size > 0;
final long base_bits_mask = final long base_bits_mask =
~((1L << (64 - bit_size)) - 1); ~((1L << (64 - bit_size)) - 1);
final boolean high_bits_zero = (this_value & base_bits_mask) == 0; final boolean high_bits_zero = (this_value & base_bits_mask) == 0;
if (high_bits_zero) { if (high_bits_zero) {
this_value *= base; this_value *= base;
} else { } else {
delayed_multipliciation = true; delayed_multiplication = true;
} }
} }
mask >>>= 1; mask >>>= 1;
} }
assignUInt64(this_value); assignUInt64(this_value);
if (delayed_multipliciation) { if (delayed_multiplication) {
multiplyByUInt32(base); multiplyByUInt32(base);
} }
@ -681,7 +683,7 @@ class Bignum {
} }
int bigitAt(final int index) { int bigitOrZero(final int index) {
if (index >= bigitLength()) return 0; if (index >= bigitLength()) return 0;
if (index < exponent_) return 0; if (index < exponent_) return 0;
return bigits_[index - exponent_]; return bigits_[index - exponent_];
@ -696,8 +698,8 @@ class Bignum {
if (bigit_length_a < bigit_length_b) return -1; if (bigit_length_a < bigit_length_b) return -1;
if (bigit_length_a > bigit_length_b) return +1; if (bigit_length_a > bigit_length_b) return +1;
for (int i = bigit_length_a - 1; i >= Math.min(a.exponent_, b.exponent_); --i) { for (int i = bigit_length_a - 1; i >= Math.min(a.exponent_, b.exponent_); --i) {
final int bigit_a = a.bigitAt(i); final int bigit_a = a.bigitOrZero(i);
final int bigit_b = b.bigitAt(i); final int bigit_b = b.bigitOrZero(i);
if (bigit_a < bigit_b) return -1; if (bigit_a < bigit_b) return -1;
if (bigit_a > bigit_b) return +1; if (bigit_a > bigit_b) return +1;
// Otherwise they are equal up to this digit. Try the next digit. // Otherwise they are equal up to this digit. Try the next digit.
@ -726,9 +728,9 @@ class Bignum {
// Starting at min_exponent all digits are == 0. So no need to compare them. // Starting at min_exponent all digits are == 0. So no need to compare them.
final int min_exponent = Math.min(Math.min(a.exponent_, b.exponent_), c.exponent_); final int min_exponent = Math.min(Math.min(a.exponent_, b.exponent_), c.exponent_);
for (int i = c.bigitLength() - 1; i >= min_exponent; --i) { for (int i = c.bigitLength() - 1; i >= min_exponent; --i) {
final int int_a = a.bigitAt(i); final int int_a = a.bigitOrZero(i);
final int int_b = b.bigitAt(i); final int int_b = b.bigitOrZero(i);
final int int_c = c.bigitAt(i); final int int_c = c.bigitOrZero(i);
final int sum = int_a + int_b; final int sum = int_a + int_b;
if (sum > int_c + borrow) { if (sum > int_c + borrow) {
return +1; return +1;

@ -286,7 +286,8 @@ class FixedDtoa {
fractionals -= (long) (digit) << point; fractionals -= (long) (digit) << point;
} }
// If the first bit after the point is set we have to round up. // If the first bit after the point is set we have to round up.
if (((fractionals >>> (point - 1)) & 1) == 1) { assert (fractionals == 0 || point - 1 >= 0);
if ((fractionals != 0) && ((fractionals >>> (point - 1)) & 1) == 1) {
roundUp(buffer); roundUp(buffer);
} }
} else { // We need 128 bits. } else { // We need 128 bits.

@ -115,7 +115,7 @@ class IeeeDouble {
} }
static double previousDouble(final long d64) { static double previousDouble(final long d64) {
if (d64 == (kInfinity | kSignMask)) return -longToDouble(kInfinity); if (d64 == (kInfinity | kSignMask)) return -Infinity();
if (sign(d64) < 0) { if (sign(d64) < 0) {
return longToDouble(d64 + 1); return longToDouble(d64 + 1);
} else { } else {

@ -69,7 +69,7 @@ import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue; import static org.testng.Assert.assertTrue;
/** /**
* FastDtoa tests * BignumDtoa tests
*/ */
@SuppressWarnings("javadoc") @SuppressWarnings("javadoc")
public class BignumDtoaTest { public class BignumDtoaTest {
@ -220,6 +220,11 @@ public class BignumDtoaTest {
assertEquals(299, buffer.getDecimalPoint()); assertEquals(299, buffer.getDecimalPoint());
buffer.reset(); buffer.reset();
DoubleConversion.bignumDtoa(1e-23, DtoaMode.SHORTEST, 0, buffer);
assertEquals("1", buffer.getRawDigits());
assertEquals(-22, buffer.getDecimalPoint());
buffer.reset();
final long smallest_normal64 = 0x0010000000000000L; final long smallest_normal64 = 0x0010000000000000L;
double v = Double.longBitsToDouble(smallest_normal64); double v = Double.longBitsToDouble(smallest_normal64);
DoubleConversion.bignumDtoa(v, DtoaMode.SHORTEST, 0, buffer); DoubleConversion.bignumDtoa(v, DtoaMode.SHORTEST, 0, buffer);

@ -624,6 +624,11 @@ public class FixedDtoaTest {
assertEquals("1000000000000000128", buffer.getRawDigits()); assertEquals("1000000000000000128", buffer.getRawDigits());
assertEquals(19, buffer.getDecimalPoint()); assertEquals(19, buffer.getDecimalPoint());
buffer.reset(); buffer.reset();
assertTrue(DoubleConversion.fixedDtoa(2.10861548515811875e+15, 17, buffer));
assertEquals("210861548515811875", buffer.getRawDigits());
assertEquals(16, buffer.getDecimalPoint());
buffer.reset();
} }

@ -41,7 +41,11 @@ import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue; import static org.testng.Assert.assertTrue;
/** /**
* Ieee class tests * IeeeDouble tests
*
* @test
* @modules jdk.scripting.nashorn/jdk.nashorn.internal.runtime.doubleconv:open
* @run testng jdk.nashorn.internal.runtime.doubleconv.test.IeeeDoubleTest
*/ */
@SuppressWarnings({"unchecked", "javadoc"}) @SuppressWarnings({"unchecked", "javadoc"})
public class IeeeDoubleTest { public class IeeeDoubleTest {