-
Notifications
You must be signed in to change notification settings - Fork 6.2k
8315585: Optimization for decimal to string #23310
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
4040d76
635882f
7ed19c8
7b82f78
edffa0f
72ed1b7
cb6786b
57cc7b2
0d2b3aa
4a857cf
057d006
a41a34b
a734f61
3ed3354
d99a963
ddc2a86
d78b07c
4ee8837
36602df
dc47c78
3842e35
7d48ac1
0a66197
dd14ca2
cb88e0e
cf43f34
0e7b30b
cf67d84
f9af0b0
a5a07ce
b4c142d
3c3b740
d7e2934
50c21ca
a95ef6e
2345fb9
32d95b3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,5 +1,6 @@ | |||||||||||||||||
| /* | |||||||||||||||||
| * Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved. | |||||||||||||||||
| * Copyright (c) 2025, Alibaba Group Holding Limited. All Rights Reserved. | |||||||||||||||||
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |||||||||||||||||
| * | |||||||||||||||||
| * This code is free software; you can redistribute it and/or modify it | |||||||||||||||||
|
|
@@ -35,6 +36,8 @@ | ||||||||||||||||
| import java.io.ObjectInputStream; | |||||||||||||||||
| import java.io.ObjectStreamException; | |||||||||||||||||
| import java.io.StreamCorruptedException; | |||||||||||||||||
| import java.nio.charset.CharacterCodingException; | |||||||||||||||||
| import java.nio.charset.StandardCharsets; | |||||||||||||||||
| import java.util.Arrays; | |||||||||||||||||
| import java.util.Objects; | |||||||||||||||||
|
|
|||||||||||||||||
|
|
@@ -3423,62 +3426,113 @@ public String toEngineeringString() { | ||||||||||||||||
| * @see #toEngineeringString() | |||||||||||||||||
| */ | |||||||||||||||||
| public String toPlainString() { | |||||||||||||||||
| if(scale==0) { | |||||||||||||||||
| if(intCompact!=INFLATED) { | |||||||||||||||||
| return Long.toString(intCompact); | |||||||||||||||||
| } else { | |||||||||||||||||
| return intVal.toString(); | |||||||||||||||||
| int scale = this.scale; | |||||||||||||||||
| if (scale == 0) | |||||||||||||||||
| return unscaledString(); | |||||||||||||||||
|
|
|||||||||||||||||
| int signum = signum(); | |||||||||||||||||
| if (scale < 0) { // No decimal point | |||||||||||||||||
| if (signum == 0) | |||||||||||||||||
| return "0"; | |||||||||||||||||
| int trailingZeros = checkScaleNonZero((-(long) scale)); | |||||||||||||||||
| String str = unscaledString(); | |||||||||||||||||
| int len = str.length() + trailingZeros; | |||||||||||||||||
| if (len < 0) { | |||||||||||||||||
| throw new OutOfMemoryError("too large to fit in a String"); | |||||||||||||||||
| } | |||||||||||||||||
| return new StringBuilder(len) | |||||||||||||||||
| .append(str) | |||||||||||||||||
| .repeat('0', trailingZeros) | |||||||||||||||||
| .toString(); | |||||||||||||||||
| } | |||||||||||||||||
| if(this.scale<0) { // No decimal point | |||||||||||||||||
| if(signum()==0) { | |||||||||||||||||
| return "0"; | |||||||||||||||||
|
|
|||||||||||||||||
| long intCompact = this.intCompact; | |||||||||||||||||
| if (intCompact != INFLATED) { | |||||||||||||||||
| long intCompactAbs = Math.abs(intCompact); | |||||||||||||||||
| if (scale == 2 & (int) intCompact == intCompactAbs) { // intCompact >= 0 && intCompact <= Integer.MAX_VALUE | |||||||||||||||||
| // currency fast path | |||||||||||||||||
| return scale2((int) intCompact); | |||||||||||||||||
| } | |||||||||||||||||
| int trailingZeros = checkScaleNonZero((-(long)scale)); | |||||||||||||||||
| String str = intCompact != INFLATED | |||||||||||||||||
| ? Long.toString(intCompact) | |||||||||||||||||
| : intVal.toString(); | |||||||||||||||||
| int len = str.length() + trailingZeros; | |||||||||||||||||
| return getCompactValueString(signum, intCompactAbs, DecimalDigits.stringSize(intCompactAbs), scale); | |||||||||||||||||
| } | |||||||||||||||||
|
|
|||||||||||||||||
| return getValueString(signum, intVal.abs().toString(), scale); | |||||||||||||||||
| } | |||||||||||||||||
|
|
|||||||||||||||||
| private static String getCompactValueString(int signum, long intCompactAbs, int intCompactAbsSize, int scale) { | |||||||||||||||||
| /* Insert decimal point */ | |||||||||||||||||
| int insertionPoint = intCompactAbsSize - scale; | |||||||||||||||||
| byte[] buf; | |||||||||||||||||
| if (insertionPoint == 0) { /* Point goes just before intVal */ | |||||||||||||||||
| buf = new byte[intCompactAbsSize + (signum < 0 ? 3 : 2)]; | |||||||||||||||||
| int off = 0; | |||||||||||||||||
| if(signum < 0) { | |||||||||||||||||
| buf[0] = '-'; | |||||||||||||||||
| off = 1; | |||||||||||||||||
| } | |||||||||||||||||
| buf[off ] = '0'; | |||||||||||||||||
| buf[off + 1] = '.'; | |||||||||||||||||
| DecimalDigits.uncheckedGetCharsLatin1(intCompactAbs, buf.length, buf); | |||||||||||||||||
| } else if (insertionPoint > 0) { /* Point goes inside intVal */ | |||||||||||||||||
| buf = new byte[intCompactAbsSize + (signum < 0 ? 2 : 1)]; | |||||||||||||||||
| if (signum < 0) { | |||||||||||||||||
| buf[0] = '-'; | |||||||||||||||||
| insertionPoint++; | |||||||||||||||||
| } | |||||||||||||||||
| long power = LONG_TEN_POWERS_TABLE[scale]; | |||||||||||||||||
| long highInt = intCompactAbs / power; | |||||||||||||||||
| long small = Math.abs(intCompactAbs - highInt * power); | |||||||||||||||||
| DecimalDigits.uncheckedGetCharsLatin1(highInt, insertionPoint, buf); | |||||||||||||||||
| buf[insertionPoint] = '.'; | |||||||||||||||||
| int smallStart = DecimalDigits.uncheckedGetCharsLatin1(small, buf.length, buf); | |||||||||||||||||
| if (smallStart > insertionPoint + 1) { // fill zeros | |||||||||||||||||
| Arrays.fill(buf, insertionPoint + 1, smallStart, (byte) '0'); | |||||||||||||||||
| } | |||||||||||||||||
| } else { /* We must insert zeros between point and intVal */ | |||||||||||||||||
| int len = (signum < 0 ? 3 : 2) + scale; | |||||||||||||||||
| if (len < 0) { | |||||||||||||||||
| throw new OutOfMemoryError("too large to fit in a String"); | |||||||||||||||||
| } | |||||||||||||||||
| StringBuilder buf = new StringBuilder(len); | |||||||||||||||||
| buf.append(str); | |||||||||||||||||
| buf.repeat('0', trailingZeros); | |||||||||||||||||
| return buf.toString(); | |||||||||||||||||
| } | |||||||||||||||||
| String str; | |||||||||||||||||
| if(intCompact!=INFLATED) { | |||||||||||||||||
| str = Long.toString(Math.abs(intCompact)); | |||||||||||||||||
| } else { | |||||||||||||||||
| str = intVal.abs().toString(); | |||||||||||||||||
| buf = new byte[len]; | |||||||||||||||||
| int off = 0; | |||||||||||||||||
| if(signum < 0) { | |||||||||||||||||
| buf[0] = '-'; | |||||||||||||||||
| off = 1; | |||||||||||||||||
| } | |||||||||||||||||
| buf[off ] = '0'; | |||||||||||||||||
| buf[off + 1] = '.'; | |||||||||||||||||
| Arrays.fill(buf, off + 2, off + 2 - insertionPoint, (byte) '0'); | |||||||||||||||||
| DecimalDigits.uncheckedGetCharsLatin1(intCompactAbs, buf.length, buf); | |||||||||||||||||
| } | |||||||||||||||||
| return getValueString(signum(), str, scale); | |||||||||||||||||
| return JLA.uncheckedNewStringWithLatin1Bytes(buf); | |||||||||||||||||
| } | |||||||||||||||||
|
|
|||||||||||||||||
| /* Returns a digit.digit string */ | |||||||||||||||||
| private static String getValueString(int signum, String intString, int scale) { | |||||||||||||||||
| /* Insert decimal point */ | |||||||||||||||||
| StringBuilder buf; | |||||||||||||||||
| int insertionPoint = intString.length() - scale; | |||||||||||||||||
| if (insertionPoint == 0) { /* Point goes just before intVal */ | |||||||||||||||||
| return (signum<0 ? "-0." : "0.") + intString; | |||||||||||||||||
| return (signum < 0 ? "-0." : "0.").concat(intString); | |||||||||||||||||
| } else if (insertionPoint > 0) { /* Point goes inside intVal */ | |||||||||||||||||
| buf = new StringBuilder(intString); | |||||||||||||||||
| buf.insert(insertionPoint, '.'); | |||||||||||||||||
| if (signum < 0) | |||||||||||||||||
| buf.insert(0, '-'); | |||||||||||||||||
| StringBuilder buf = new StringBuilder(); | |||||||||||||||||
| if (signum < 0) { | |||||||||||||||||
| buf.append('-'); | |||||||||||||||||
| insertionPoint++; | |||||||||||||||||
| } | |||||||||||||||||
| return buf.append(intString) | |||||||||||||||||
| .insert(insertionPoint, '.') | |||||||||||||||||
| .toString(); | |||||||||||||||||
| } else { /* We must insert zeros between point and intVal */ | |||||||||||||||||
| int len = (signum < 0 ? 3 : 2) + scale; | |||||||||||||||||
| if (len < 0) { | |||||||||||||||||
| throw new OutOfMemoryError("too large to fit in a String"); | |||||||||||||||||
| } | |||||||||||||||||
| buf = new StringBuilder(len); | |||||||||||||||||
| buf.append(signum<0 ? "-0." : "0."); | |||||||||||||||||
| buf.repeat('0', -insertionPoint); // insertionPoint != MIN_VALUE | |||||||||||||||||
| buf.append(intString); | |||||||||||||||||
| return new StringBuilder(len) | |||||||||||||||||
| .append(signum<0 ? "-0." : "0.") | |||||||||||||||||
| .repeat('0', -insertionPoint) // insertionPoint != MIN_VALUE | |||||||||||||||||
| .append(intString) | |||||||||||||||||
| .toString(); | |||||||||||||||||
| } | |||||||||||||||||
| return buf.toString(); | |||||||||||||||||
| } | |||||||||||||||||
|
|
|||||||||||||||||
| /** | |||||||||||||||||
|
|
@@ -4125,75 +4179,67 @@ public BigDecimal ulp() { | ||||||||||||||||
| * {@code BigDecimal} | |||||||||||||||||
| */ | |||||||||||||||||
| private String layoutChars(boolean sci) { | |||||||||||||||||
| long intCompact = this.intCompact; | |||||||||||||||||
| int scale = this.scale; | |||||||||||||||||
| if (scale == 0) // zero scale is trivial | |||||||||||||||||
| return (intCompact != INFLATED) ? | |||||||||||||||||
| Long.toString(intCompact): | |||||||||||||||||
| intVal.toString(); | |||||||||||||||||
| if (scale == 2 && | |||||||||||||||||
| intCompact >= 0 && intCompact < Integer.MAX_VALUE) { | |||||||||||||||||
| // currency fast path | |||||||||||||||||
| int lowInt = (int)intCompact % 100; | |||||||||||||||||
| int highInt = (int)intCompact / 100; | |||||||||||||||||
| int highIntSize = DecimalDigits.stringSize(highInt); | |||||||||||||||||
| byte[] buf = new byte[highIntSize + 3]; | |||||||||||||||||
| DecimalDigits.uncheckedGetCharsLatin1(highInt, highIntSize, buf); | |||||||||||||||||
| buf[highIntSize] = '.'; | |||||||||||||||||
| DecimalDigits.uncheckedPutPairLatin1(buf, highIntSize + 1, lowInt); | |||||||||||||||||
| return JLA.uncheckedNewStringWithLatin1Bytes(buf); | |||||||||||||||||
| } | |||||||||||||||||
|
|
|||||||||||||||||
| char[] coeff; | |||||||||||||||||
| int offset; // offset is the starting index for coeff array | |||||||||||||||||
| // Get the significand as an absolute value | |||||||||||||||||
| return unscaledString(); | |||||||||||||||||
|
|
|||||||||||||||||
| long intCompact = this.intCompact, adjusted; | |||||||||||||||||
| int signum, coeffLen; | |||||||||||||||||
| // the significand as an absolute value | |||||||||||||||||
| String coeff; | |||||||||||||||||
| if (intCompact != INFLATED) { | |||||||||||||||||
| // All non negative longs can be made to fit into 19 character array. | |||||||||||||||||
| coeff = new char[19]; | |||||||||||||||||
| offset = DecimalDigits.getChars(Math.abs(intCompact), coeff.length, coeff); | |||||||||||||||||
| long intCompactAbs = Math.abs(intCompact); | |||||||||||||||||
| if (scale == 2 && (int) intCompact == intCompactAbs) { | |||||||||||||||||
| // currency fast path | |||||||||||||||||
| return scale2((int) intCompact); | |||||||||||||||||
| } | |||||||||||||||||
| coeffLen = DecimalDigits.stringSize(intCompactAbs); | |||||||||||||||||
| signum = Long.signum(intCompact); | |||||||||||||||||
| adjusted = -(long)scale + (coeffLen -1); | |||||||||||||||||
| if ((scale >= 0) & (adjusted >= -6)) { // plain number | |||||||||||||||||
| return getCompactValueString(signum, intCompactAbs, coeffLen, scale); | |||||||||||||||||
| } | |||||||||||||||||
| byte[] buf = new byte[coeffLen]; | |||||||||||||||||
| DecimalDigits.uncheckedGetCharsLatin1(intCompactAbs, buf.length, buf); | |||||||||||||||||
| coeff = JLA.uncheckedNewStringWithLatin1Bytes(buf); | |||||||||||||||||
| } else { | |||||||||||||||||
| offset = 0; | |||||||||||||||||
| coeff = intVal.abs().toString().toCharArray(); | |||||||||||||||||
| signum = intVal.signum(); | |||||||||||||||||
| coeff = intVal.abs().toString(); | |||||||||||||||||
| coeffLen = coeff.length(); | |||||||||||||||||
|
|
|||||||||||||||||
| // Construct a buffer, with sufficient capacity for all cases. | |||||||||||||||||
| // If E-notation is needed, length will be: +1 if negative, +1 | |||||||||||||||||
| // if '.' needed, +2 for "E+", + up to 10 for adjusted exponent. | |||||||||||||||||
| // Otherwise it could have +1 if negative, plus leading "0.00000" | |||||||||||||||||
| adjusted = -(long) scale + (coeffLen - 1); | |||||||||||||||||
| if ((scale >= 0) && (adjusted >= -6)) { // plain number | |||||||||||||||||
| return getValueString(signum, coeff, scale); | |||||||||||||||||
| } | |||||||||||||||||
| } | |||||||||||||||||
|
|
|||||||||||||||||
| // Construct a buffer, with sufficient capacity for all cases. | |||||||||||||||||
| // If E-notation is needed, length will be: +1 if negative, +1 | |||||||||||||||||
| // if '.' needed, +2 for "E+", + up to 10 for adjusted exponent. | |||||||||||||||||
| // Otherwise it could have +1 if negative, plus leading "0.00000" | |||||||||||||||||
| StringBuilder buf = new StringBuilder(32);; | |||||||||||||||||
| if (signum() < 0) // prefix '-' if negative | |||||||||||||||||
| // E-notation is needed | |||||||||||||||||
| return layoutCharsE(sci, coeff, coeffLen, adjusted); | |||||||||||||||||
| } | |||||||||||||||||
|
|
|||||||||||||||||
| private String layoutCharsE(boolean sci, String coeff, int coeffLen, long adjusted) { | |||||||||||||||||
| StringBuilder buf = new StringBuilder(coeffLen + 14); | |||||||||||||||||
| int signum = signum(); | |||||||||||||||||
| if (signum < 0) // prefix '-' if negative | |||||||||||||||||
| buf.append('-'); | |||||||||||||||||
| int coeffLen = coeff.length - offset; | |||||||||||||||||
| long adjusted = -(long)scale + (coeffLen -1); | |||||||||||||||||
| if ((scale >= 0) && (adjusted >= -6)) { // plain number | |||||||||||||||||
| int pad = scale - coeffLen; // count of padding zeros | |||||||||||||||||
| if (pad >= 0) { // 0.xxx form | |||||||||||||||||
| buf.append('0'); | |||||||||||||||||
| buf.append('.'); | |||||||||||||||||
| for (; pad>0; pad--) { | |||||||||||||||||
| buf.append('0'); | |||||||||||||||||
| } | |||||||||||||||||
| buf.append(coeff, offset, coeffLen); | |||||||||||||||||
| } else { // xx.xx form | |||||||||||||||||
| buf.append(coeff, offset, -pad); | |||||||||||||||||
| buf.append('.'); | |||||||||||||||||
| buf.append(coeff, -pad + offset, scale); | |||||||||||||||||
| if (sci) { // Scientific notation | |||||||||||||||||
| buf.append(coeff.charAt(0)); // first character | |||||||||||||||||
| if (coeffLen > 1) { // more to come | |||||||||||||||||
| buf.append('.') | |||||||||||||||||
| .append(coeff, 1, coeffLen); | |||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this right that the old end is
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we use In the original code, coeff = new char[19];
offset = DecimalDigits.getChars(Math.abs(intCompact), coeff.length, coeff);The code that was called: In the new code, coeff is generated as follows: byte[] buf = new byte[coeffLen];
DecimalDigits.uncheckedGetCharsLatin1(intCompactAbs, buf.length, buf);
coeff = newStringNoRepl(buf);The method call has also been changed from
|
|||||||||||||||||
| } | |||||||||||||||||
| } else { // E-notation is needed | |||||||||||||||||
| if (sci) { // Scientific notation | |||||||||||||||||
| buf.append(coeff[offset]); // first character | |||||||||||||||||
| if (coeffLen > 1) { // more to come | |||||||||||||||||
| buf.append('.'); | |||||||||||||||||
| buf.append(coeff, offset + 1, coeffLen - 1); | |||||||||||||||||
| } | |||||||||||||||||
| } else { // Engineering notation | |||||||||||||||||
| int sig = (int)(adjusted % 3); | |||||||||||||||||
| if (sig < 0) | |||||||||||||||||
| sig += 3; // [adjusted was negative] | |||||||||||||||||
| adjusted -= sig; // now a multiple of 3 | |||||||||||||||||
| sig++; | |||||||||||||||||
| if (signum() == 0) { | |||||||||||||||||
| switch (sig) { | |||||||||||||||||
| } else { // Engineering notation | |||||||||||||||||
| int sig = (int)(adjusted % 3); | |||||||||||||||||
| if (sig < 0) | |||||||||||||||||
| sig += 3; // [adjusted was negative] | |||||||||||||||||
| adjusted -= sig; // now a multiple of 3 | |||||||||||||||||
| sig++; | |||||||||||||||||
| if (signum == 0) { | |||||||||||||||||
| switch (sig) { | |||||||||||||||||
| case 1: | |||||||||||||||||
| buf.append('0'); // exponent is a multiple of three | |||||||||||||||||
| break; | |||||||||||||||||
|
|
@@ -4207,29 +4253,45 @@ private String layoutChars(boolean sci) { | ||||||||||||||||
| break; | |||||||||||||||||
| default: | |||||||||||||||||
| throw new AssertionError("Unexpected sig value " + sig); | |||||||||||||||||
| } | |||||||||||||||||
| } else if (sig >= coeffLen) { // significand all in integer | |||||||||||||||||
| buf.append(coeff, offset, coeffLen); | |||||||||||||||||
| // may need some zeros, too | |||||||||||||||||
| for (int i = sig - coeffLen; i > 0; i--) { | |||||||||||||||||
| buf.append('0'); | |||||||||||||||||
| } | |||||||||||||||||
| } else { // xx.xxE form | |||||||||||||||||
| buf.append(coeff, offset, sig); | |||||||||||||||||
| buf.append('.'); | |||||||||||||||||
| buf.append(coeff, offset + sig, coeffLen - sig); | |||||||||||||||||
| } | |||||||||||||||||
| } else if (sig >= coeffLen) {// significand all in integer | |||||||||||||||||
| buf.append(coeff, 0, coeffLen) | |||||||||||||||||
| .repeat('0', sig - coeffLen); // may need some zeros, too | |||||||||||||||||
| } else { // xx.xxE form | |||||||||||||||||
| buf.append(coeff, 0, sig) | |||||||||||||||||
| .append('.') | |||||||||||||||||
| .append(coeff, sig, coeffLen); | |||||||||||||||||
| } | |||||||||||||||||
| if (adjusted != 0) { // [!sci could have made 0] | |||||||||||||||||
| buf.append('E'); | |||||||||||||||||
| if (adjusted > 0) // force sign for positive | |||||||||||||||||
| buf.append('+'); | |||||||||||||||||
| buf.append(adjusted); | |||||||||||||||||
| } | |||||||||||||||||
| } | |||||||||||||||||
| if (adjusted != 0) { // [!sci could have made 0] | |||||||||||||||||
| buf.append('E'); | |||||||||||||||||
| if (adjusted > 0) // force sign for positive | |||||||||||||||||
| buf.append('+'); | |||||||||||||||||
| buf.append(adjusted); | |||||||||||||||||
| } | |||||||||||||||||
| return buf.toString(); | |||||||||||||||||
| } | |||||||||||||||||
|
|
|||||||||||||||||
| /** | |||||||||||||||||
| * currency fast path | |||||||||||||||||
| */ | |||||||||||||||||
| private static String scale2(int intCompact) { | |||||||||||||||||
| int highInt = intCompact / 100; | |||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Something to experiment with here: int highInt = intCompact / 100;
int lowInt = intCompact - highInt * 100;
short packed=DecimalDigits.pair(lowInt);
return new StringBuilder()
.append(highInt)
.append('.')
.append((char) (packed & 0xFF))
.append((char) (packed >> 8))
.toString();C2 seems to be able to optimize out the SB here, so it might do as well as
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good suggestion, but DecimalDigits no longer provides a pair method
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right - you’d need to add it back to try this
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tested it on a MacBook M1 Max machine and the results were different from what you said. Using StringBuilder + digitPair would degrade performance. git remote add wenshao git@github.com:wenshao/jdk.git
git fetch wenshao
# use JLA
git checkout f9af0b0203145b95d82a2067a10bde61b0915dd7
make test TEST="micro:java.math.BigDecimals.smallScale2"
# use digitPair
git checkout 4124121933e08ab185f3f879856197ed15caafd7
make test TEST="micro:java.math.BigDecimals.smallScale2"Benchmark Mode Cnt Score Error Units (f9af0b02031)
BigDecimals.smallScale2EngineeringToString avgt 15 9.658 ? 0.228 ns/op
BigDecimals.smallScale2LayoutCharsToString avgt 15 9.597 ? 0.047 ns/op
BigDecimals.smallScale2PlainToString avgt 15 9.759 ? 0.054 ns/op
Benchmark Mode Cnt Score Error Units (4124121933e)
BigDecimals.smallScale2EngineeringToString avgt 15 18.763 ? 0.332 ns/op
BigDecimals.smallScale2LayoutCharsToString avgt 15 18.738 ? 0.214 ns/op
BigDecimals.smallScale2PlainToString avgt 15 18.992 ? 0.226 ns/op |
|||||||||||||||||
| int lowInt = intCompact - highInt * 100; | |||||||||||||||||
| int highIntSize = DecimalDigits.stringSize(highInt); | |||||||||||||||||
| byte[] buf = new byte[highIntSize + 3]; | |||||||||||||||||
| DecimalDigits.uncheckedPutPairLatin1(buf, highIntSize + 1, lowInt); | |||||||||||||||||
| buf[highIntSize] = '.'; | |||||||||||||||||
| DecimalDigits.uncheckedGetCharsLatin1(highInt, highIntSize, buf); | |||||||||||||||||
| return JLA.uncheckedNewStringWithLatin1Bytes(buf); | |||||||||||||||||
| } | |||||||||||||||||
|
|
|||||||||||||||||
| private String unscaledString() { | |||||||||||||||||
| return intCompact != INFLATED | |||||||||||||||||
| ? Long.toString(intCompact) | |||||||||||||||||
| : intVal.toString(); | |||||||||||||||||
| } | |||||||||||||||||
|
|
|||||||||||||||||
| /** | |||||||||||||||||
| * Return 10 to the power n, as a {@code BigInteger}. | |||||||||||||||||
| * | |||||||||||||||||
|
|
|||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.