Skip to content

Commit

Permalink
Merge pull request #2940 from jialeicui/master
Browse files Browse the repository at this point in the history
Fixed overflow issue when handling large inputs in QuantityFormatter
  • Loading branch information
k8s-ci-robot authored Dec 12, 2023
2 parents 2622118 + 042e2f0 commit 279d612
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
package io.kubernetes.client.custom;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.MathContext;
import org.apache.commons.lang3.tuple.Pair;

Expand Down Expand Up @@ -64,43 +65,43 @@ private boolean isFractional(Quantity quantity) {

private String toBase1024String(final Quantity quantity) {
final BigDecimal amount = quantity.getNumber();
final long value = amount.unscaledValue().longValue();
final BigInteger value = amount.unscaledValue();
final int exponent = -amount.scale();
final Pair<Long, Integer> resultAndTimes = removeFactorsForBase(value, 1024);
final Pair<BigInteger, Integer> resultAndTimes = removeFactorsForBase(value, BigInteger.valueOf(1024));
return resultAndTimes.getLeft()
+ new SuffixFormatter()
.format(quantity.getFormat(), exponent + resultAndTimes.getRight() * 10);
}

private String toBase10String(final Quantity quantity) {
final BigDecimal amount = quantity.getNumber();
final long value = amount.unscaledValue().longValue();
final BigInteger value = amount.unscaledValue();
final int exponent = -amount.scale();
final Pair<Long, Integer> resultAndTimes = removeFactorsForBase(value, 10);
final Pair<BigInteger, Integer> resultAndTimes = removeFactorsForBase(value, BigInteger.TEN);
final int postFactoringExponent = exponent + resultAndTimes.getRight();
final Pair<Long, Integer> valueAndExponent =
final Pair<BigInteger, Integer> valueAndExponent =
ensureExponentIsMultipleOf3(resultAndTimes.getLeft(), postFactoringExponent);
return valueAndExponent.getLeft()
+ new SuffixFormatter().format(quantity.getFormat(), valueAndExponent.getRight());
}

private Pair<Long, Integer> ensureExponentIsMultipleOf3(final long mantissa, final int exponent) {
private Pair<BigInteger, Integer> ensureExponentIsMultipleOf3(final BigInteger mantissa, final int exponent) {
final long exponentRemainder = exponent % 3;
if (exponentRemainder == 1 || exponentRemainder == -2) {
return Pair.of(mantissa * 10, exponent - 1);
return Pair.of(mantissa.multiply(BigInteger.TEN), exponent - 1);
} else if (exponentRemainder == -1 || exponentRemainder == 2) {
return Pair.of(mantissa * 100, exponent - 2);
return Pair.of(mantissa.multiply(BigInteger.valueOf(100)), exponent - 2);
} else {
return Pair.of(mantissa, exponent);
}
}

private Pair<Long, Integer> removeFactorsForBase(final long value, final int base) {
private Pair<BigInteger, Integer> removeFactorsForBase(final BigInteger value, final BigInteger base) {
int times = 0;
long result = value;
while (result >= base && result % base == 0) {
BigInteger result = value;
while (result.compareTo(base) >= 0 && result.mod(base).equals(BigInteger.ZERO)) {
times++;
result = result / base;
result = result.divide(base);
}
return Pair.of(result, times);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,4 +179,12 @@ public void testFormatNoExpDecimalExponent() {
.format(new Quantity(BigDecimal.valueOf(12345), Quantity.Format.DECIMAL_EXPONENT));
assertThat(formattedString, is("12345"));
}

@Test
public void testFormatLargeDecimalExponent() {
final String formattedString2 =
new QuantityFormatter()
.format(new Quantity(Float.toString(123456789012.f)));
assertThat(formattedString2, is("123456791e3"));
}
}

0 comments on commit 279d612

Please sign in to comment.