From ac0b1c60b40f92b33467133ad68d678026df6c6c Mon Sep 17 00:00:00 2001 From: Min Jin Date: Thu, 22 Oct 2026 10:27:27 -0700 Subject: [PATCH] fix(quantity): format negative quantities with SI/binary suffixes QuantityFormatter.removeFactorsForBase used result.compareTo(base) >= 0 as the loop guard, which is always false for negative unscaled values, so negative quantities were never reduced to a suffixed form. As a result Quantity.toSuffixedString() returned e.g. "-100000" instead of "-100k" and "-1048576" instead of "-1Mi". Guard on the absolute value so the factor-removal loop runs for negative magnitudes too. BigInteger.mod already returns a non-negative remainder and divide handles negative values, so the divisibility check and downstream exponent math are unchanged for positive inputs. Add focused unit tests covering negative DECIMAL_SI and BINARY_SI formatting (fail before, pass after). --- .../client/custom/QuantityFormatter.java | 2 +- .../client/custom/QuantityFormatterTest.java | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/kubernetes/src/main/java/io/kubernetes/client/custom/QuantityFormatter.java b/kubernetes/src/main/java/io/kubernetes/client/custom/QuantityFormatter.java index 0f15eacad2..92f36ee089 100644 --- a/kubernetes/src/main/java/io/kubernetes/client/custom/QuantityFormatter.java +++ b/kubernetes/src/main/java/io/kubernetes/client/custom/QuantityFormatter.java @@ -99,7 +99,7 @@ private Pair ensureExponentIsMultipleOf3(final BigInteger m private Pair removeFactorsForBase(final BigInteger value, final BigInteger base) { int times = 0; BigInteger result = value; - while (result.compareTo(base) >= 0 && result.mod(base).equals(BigInteger.ZERO)) { + while (result.abs().compareTo(base) >= 0 && result.mod(base).equals(BigInteger.ZERO)) { times++; result = result.divide(base); } diff --git a/kubernetes/src/test/java/io/kubernetes/client/custom/QuantityFormatterTest.java b/kubernetes/src/test/java/io/kubernetes/client/custom/QuantityFormatterTest.java index 324dd225c9..3ce500c60f 100644 --- a/kubernetes/src/test/java/io/kubernetes/client/custom/QuantityFormatterTest.java +++ b/kubernetes/src/test/java/io/kubernetes/client/custom/QuantityFormatterTest.java @@ -155,6 +155,22 @@ void formatFractionalBinarySi() { assertThat(formattedString).isEqualTo("123123m"); } + @Test + void formatNegativeDecimalSi() { + final String formattedString = + new QuantityFormatter() + .format(new Quantity(new BigDecimal("-100000"), Quantity.Format.DECIMAL_SI)); + assertThat(formattedString).isEqualTo("-100k"); + } + + @Test + void formatNegativeBinarySi() { + final String formattedString = + new QuantityFormatter() + .format(new Quantity(new BigDecimal(2).pow(20).negate(), Quantity.Format.BINARY_SI)); + assertThat(formattedString).isEqualTo("-1Mi"); + } + @Test void formatDecimalExponent() { final String formattedString =