View | Details | Raw Unified | Return to bug 63842
Collapse All | Expand All

(-)a/src/java/org/apache/poi/ss/usermodel/FractionFormat.java (-18 / +22 lines)
Lines 16-21 Link Here
16
 */
16
 */
17
17
18
package org.apache.poi.ss.usermodel;
18
package org.apache.poi.ss.usermodel;
19
import java.math.BigDecimal;
19
import java.text.FieldPosition;
20
import java.text.FieldPosition;
20
import java.text.Format;
21
import java.text.Format;
21
import java.text.ParsePosition;
22
import java.text.ParsePosition;
Lines 99-112 public class FractionFormat extends Format { Link Here
99
100
100
    public String format(Number num) {
101
    public String format(Number num) {
101
102
102
        final double doubleValue = num.doubleValue();
103
        final BigDecimal doubleValue = new BigDecimal(num.doubleValue());
103
        
104
        
104
        final boolean isNeg = (doubleValue < 0.0f) ? true : false;
105
        final boolean isNeg = doubleValue.compareTo(BigDecimal.ZERO) < 0;
105
        final double absDoubleValue = Math.abs(doubleValue);
106
106
        
107
        final BigDecimal absValue = doubleValue.abs();
107
        final double wholePart = Math.floor(absDoubleValue);
108
        final BigDecimal wholePart = new BigDecimal(absValue.toBigInteger());
108
        final double decPart = absDoubleValue - wholePart;
109
        final BigDecimal decPart = absValue.remainder(BigDecimal.ONE);
109
        if (wholePart + decPart == 0) {
110
111
        if (wholePart.add(decPart).compareTo(BigDecimal.ZERO) == 0) {
110
            return "0";
112
            return "0";
111
        }
113
        }
112
        
114
        
Lines 119-131 public class FractionFormat extends Format { Link Here
119
        // }
121
        // }
120
        
122
        
121
        //this is necessary to prevent overflow in the maxDenom calculation
123
        //this is necessary to prevent overflow in the maxDenom calculation
122
        if (Double.compare(decPart, 0) == 0){
124
        if (decPart.compareTo(BigDecimal.ZERO) == 0){
123
            
125
            
124
            StringBuilder sb = new StringBuilder();
126
            StringBuilder sb = new StringBuilder();
125
            if (isNeg){
127
            if (isNeg){
126
                sb.append("-");
128
                sb.append("-");
127
            }
129
            }
128
            sb.append((int)wholePart);
130
            sb.append(wholePart);
129
            return sb.toString();
131
            return sb.toString();
130
        }
132
        }
131
        
133
        
Lines 133-145 public class FractionFormat extends Format { Link Here
133
        try{
135
        try{
134
            //this should be the case because of the constructor
136
            //this should be the case because of the constructor
135
            if (exactDenom > 0){
137
            if (exactDenom > 0){
136
                fract = SimpleFraction.buildFractionExactDenominator(decPart, exactDenom);
138
                fract = SimpleFraction.buildFractionExactDenominator(decPart.doubleValue(), exactDenom);
137
            } else {
139
            } else {
138
                fract = SimpleFraction.buildFractionMaxDenominator(decPart, maxDenom);
140
                fract = SimpleFraction.buildFractionMaxDenominator(decPart.doubleValue(), maxDenom);
139
            }
141
            }
140
        } catch (RuntimeException e){
142
        } catch (RuntimeException e){
141
            LOGGER.log(POILogger.WARN, "Can't format fraction", e);
143
            LOGGER.log(POILogger.WARN, "Can't format fraction", e);
142
            return Double.toString(doubleValue);
144
            return Double.toString(doubleValue.doubleValue());
143
        }
145
        }
144
146
145
        StringBuilder sb = new StringBuilder();
147
        StringBuilder sb = new StringBuilder();
Lines 151-173 public class FractionFormat extends Format { Link Here
151
        
153
        
152
        //if whole part has to go into the numerator
154
        //if whole part has to go into the numerator
153
        if (wholePartFormatString == null || wholePartFormatString.isEmpty()){
155
        if (wholePartFormatString == null || wholePartFormatString.isEmpty()){
154
            int trueNum = (fract.getDenominator()*(int)wholePart)+fract.getNumerator();
156
            final int fden = fract.getDenominator();
155
            sb.append(trueNum).append("/").append(fract.getDenominator());
157
            final int fnum = fract.getNumerator();
158
            BigDecimal trueNum = wholePart.multiply(new BigDecimal(fden)).add(new BigDecimal(fnum));
159
            sb.append(trueNum.toBigInteger()).append("/").append(fden);
156
            return sb.toString();
160
            return sb.toString();
157
        }
161
        }
158
        
162
        
159
        
163
        
160
        //short circuit if fraction is 0 or 1
164
        //short circuit if fraction is 0 or 1
161
        if (fract.getNumerator() == 0){
165
        if (fract.getNumerator() == 0){
162
            sb.append(Integer.toString((int)wholePart));
166
            sb.append(wholePart);
163
            return sb.toString();
167
            return sb.toString();
164
        } else if (fract.getNumerator() == fract.getDenominator()){
168
        } else if (fract.getNumerator() == fract.getDenominator()){
165
            sb.append(Integer.toString((int)wholePart+1));
169
            sb.append(wholePart.add(BigDecimal.ONE));
166
            return sb.toString();
170
            return sb.toString();
167
        }
171
        }
168
       //as mentioned above, this ignores the exact space formatting in Excel
172
       //as mentioned above, this ignores the exact space formatting in Excel
169
        if (wholePart > 0){
173
        if (wholePart.compareTo(BigDecimal.ZERO) > 0){
170
            sb.append(Integer.toString((int)wholePart)).append(" ");
174
            sb.append(wholePart).append(" ");
171
        }
175
        }
172
        sb.append(fract.getNumerator()).append("/").append(fract.getDenominator());
176
        sb.append(fract.getNumerator()).append("/").append(fract.getDenominator());
173
        return sb.toString();
177
        return sb.toString();
(-)a/src/testcases/org/apache/poi/ss/usermodel/TestFractionFormat.java (+16 lines)
Lines 41-46 public final class TestFractionFormat { Link Here
41
        String ret = f.format(val);
41
        String ret = f.format(val);
42
        assertEquals("26027/81", ret);
42
        assertEquals("26027/81", ret);
43
    }
43
    }
44
    
45
    @Test
46
    public void testWithBigWholePart() throws Exception {
47
        FractionFormat f = new FractionFormat("#", "???/???");
48
        
49
        assertEquals("10100136259702", f.format(10100136259702d));
50
        assertEquals("-10100136259702", f.format(-10100136259702d));
51
        
52
        // Excel displays fraction: 51/512
53
        assertEquals("10100136259702 10/100", f.format(10100136259702.1d));
54
        assertEquals("-10100136259702 10/100", f.format(-10100136259702.1d));
55
        
56
        // Excel displays fraction: 461/512
57
        assertEquals("10100136259702 90/100", f.format(10100136259702.9d));
58
        assertEquals("-10100136259702 90/100", f.format(-10100136259702.9d));
59
    }
44
     
60
     
45
    @Test
61
    @Test
46
    public void testTruthFile() throws Exception {
62
    public void testTruthFile() throws Exception {

Return to bug 63842