aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPJ Fanning <fanningpj@apache.org>2019-10-14 08:19:15 +0000
committerPJ Fanning <fanningpj@apache.org>2019-10-14 08:19:15 +0000
commit08b68b51414051ab7fc19aa1db4bd1a73915fd90 (patch)
tree7659442452fe2d9dd759544cd2bac2d24b60fc6b /src
parentab5bb384bb42f569c2425b45458125da39bd9d59 (diff)
downloadpoi-08b68b51414051ab7fc19aa1db4bd1a73915fd90.tar.gz
poi-08b68b51414051ab7fc19aa1db4bd1a73915fd90.zip
[bug-63842] FractionFormat casts whole part of the value into 'int'
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1868425 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
-rw-r--r--src/java/org/apache/poi/ss/usermodel/FractionFormat.java41
-rw-r--r--src/testcases/org/apache/poi/ss/usermodel/TestFractionFormat.java16
2 files changed, 39 insertions, 18 deletions
diff --git a/src/java/org/apache/poi/ss/usermodel/FractionFormat.java b/src/java/org/apache/poi/ss/usermodel/FractionFormat.java
index d90d50068b..3d95698134 100644
--- a/src/java/org/apache/poi/ss/usermodel/FractionFormat.java
+++ b/src/java/org/apache/poi/ss/usermodel/FractionFormat.java
@@ -16,6 +16,8 @@
*/
package org.apache.poi.ss.usermodel;
+
+import java.math.BigDecimal;
import java.text.FieldPosition;
import java.text.Format;
import java.text.ParsePosition;
@@ -99,14 +101,15 @@ public class FractionFormat extends Format {
public String format(Number num) {
- final double doubleValue = num.doubleValue();
-
- final boolean isNeg = (doubleValue < 0.0f) ? true : false;
- final double absDoubleValue = Math.abs(doubleValue);
+ final BigDecimal doubleValue = new BigDecimal(num.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 +122,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 +136,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 +154,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 e99c3fe698..dd08f6d799 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 {