ASF Bugzilla – Attachment 36825 Details for
Bug 63842
FractionFormat casts whole part of the value into 'int'
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
A possible quick fix for the issue
fraction_format.patch (text/plain), 5.56 KB, created by
maksut
on 2019-10-14 08:03:41 UTC
(
hide
)
Description:
A possible quick fix for the issue
Filename:
MIME Type:
Creator:
maksut
Created:
2019-10-14 08:03:41 UTC
Size:
5.56 KB
patch
obsolete
>diff --git a/src/java/org/apache/poi/ss/usermodel/FractionFormat.java b/src/java/org/apache/poi/ss/usermodel/FractionFormat.java >index d90d50068..29c650769 100644 >--- a/src/java/org/apache/poi/ss/usermodel/FractionFormat.java >+++ b/src/java/org/apache/poi/ss/usermodel/FractionFormat.java >@@ -16,6 +16,7 @@ > */ > > package org.apache.poi.ss.usermodel; >+import java.math.BigDecimal; > import java.text.FieldPosition; > import java.text.Format; > import java.text.ParsePosition; >@@ -99,14 +100,15 @@ public class FractionFormat extends Format { > > public String format(Number num) { > >- final double doubleValue = num.doubleValue(); >+ final BigDecimal doubleValue = new BigDecimal(num.doubleValue()); > >- final boolean isNeg = (doubleValue < 0.0f) ? true : false; >- final double absDoubleValue = Math.abs(doubleValue); >- >- final double wholePart = Math.floor(absDoubleValue); >- final double decPart = absDoubleValue - wholePart; >- if (wholePart + decPart == 0) { >+ final boolean isNeg = doubleValue.compareTo(BigDecimal.ZERO) < 0; >+ >+ final BigDecimal absValue = doubleValue.abs(); >+ final BigDecimal wholePart = new BigDecimal(absValue.toBigInteger()); >+ final BigDecimal decPart = absValue.remainder(BigDecimal.ONE); >+ >+ if (wholePart.add(decPart).compareTo(BigDecimal.ZERO) == 0) { > return "0"; > } > >@@ -119,13 +121,13 @@ public class FractionFormat extends Format { > // } > > //this is necessary to prevent overflow in the maxDenom calculation >- if (Double.compare(decPart, 0) == 0){ >+ if (decPart.compareTo(BigDecimal.ZERO) == 0){ > > StringBuilder sb = new StringBuilder(); > if (isNeg){ > sb.append("-"); > } >- sb.append((int)wholePart); >+ sb.append(wholePart); > return sb.toString(); > } > >@@ -133,13 +135,13 @@ public class FractionFormat extends Format { > try{ > //this should be the case because of the constructor > if (exactDenom > 0){ >- fract = SimpleFraction.buildFractionExactDenominator(decPart, exactDenom); >+ fract = SimpleFraction.buildFractionExactDenominator(decPart.doubleValue(), exactDenom); > } else { >- fract = SimpleFraction.buildFractionMaxDenominator(decPart, maxDenom); >+ fract = SimpleFraction.buildFractionMaxDenominator(decPart.doubleValue(), maxDenom); > } > } catch (RuntimeException e){ > LOGGER.log(POILogger.WARN, "Can't format fraction", e); >- return Double.toString(doubleValue); >+ return Double.toString(doubleValue.doubleValue()); > } > > StringBuilder sb = new StringBuilder(); >@@ -151,23 +153,25 @@ public class FractionFormat extends Format { > > //if whole part has to go into the numerator > if (wholePartFormatString == null || wholePartFormatString.isEmpty()){ >- int trueNum = (fract.getDenominator()*(int)wholePart)+fract.getNumerator(); >- sb.append(trueNum).append("/").append(fract.getDenominator()); >+ final int fden = fract.getDenominator(); >+ final int fnum = fract.getNumerator(); >+ BigDecimal trueNum = wholePart.multiply(new BigDecimal(fden)).add(new BigDecimal(fnum)); >+ sb.append(trueNum.toBigInteger()).append("/").append(fden); > return sb.toString(); > } > > > //short circuit if fraction is 0 or 1 > if (fract.getNumerator() == 0){ >- sb.append(Integer.toString((int)wholePart)); >+ sb.append(wholePart); > return sb.toString(); > } else if (fract.getNumerator() == fract.getDenominator()){ >- sb.append(Integer.toString((int)wholePart+1)); >+ sb.append(wholePart.add(BigDecimal.ONE)); > return sb.toString(); > } > //as mentioned above, this ignores the exact space formatting in Excel >- if (wholePart > 0){ >- sb.append(Integer.toString((int)wholePart)).append(" "); >+ if (wholePart.compareTo(BigDecimal.ZERO) > 0){ >+ sb.append(wholePart).append(" "); > } > sb.append(fract.getNumerator()).append("/").append(fract.getDenominator()); > return sb.toString(); >diff --git a/src/testcases/org/apache/poi/ss/usermodel/TestFractionFormat.java b/src/testcases/org/apache/poi/ss/usermodel/TestFractionFormat.java >index e99c3fe69..dd08f6d79 100644 >--- a/src/testcases/org/apache/poi/ss/usermodel/TestFractionFormat.java >+++ b/src/testcases/org/apache/poi/ss/usermodel/TestFractionFormat.java >@@ -41,6 +41,22 @@ public final class TestFractionFormat { > String ret = f.format(val); > assertEquals("26027/81", ret); > } >+ >+ @Test >+ public void testWithBigWholePart() throws Exception { >+ FractionFormat f = new FractionFormat("#", "???/???"); >+ >+ assertEquals("10100136259702", f.format(10100136259702d)); >+ assertEquals("-10100136259702", f.format(-10100136259702d)); >+ >+ // Excel displays fraction: 51/512 >+ assertEquals("10100136259702 10/100", f.format(10100136259702.1d)); >+ assertEquals("-10100136259702 10/100", f.format(-10100136259702.1d)); >+ >+ // Excel displays fraction: 461/512 >+ assertEquals("10100136259702 90/100", f.format(10100136259702.9d)); >+ assertEquals("-10100136259702 90/100", f.format(-10100136259702.9d)); >+ } > > @Test > public void testTruthFile() throws Exception {
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 63842
: 36825