279 lines
13 KiB
Java
279 lines
13 KiB
Java
/* ====================================================================
|
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
|
contributor license agreements. See the NOTICE file distributed with
|
|
this work for additional information regarding copyright ownership.
|
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
|
(the "License"); you may not use this file except in compliance with
|
|
the License. You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
==================================================================== */
|
|
|
|
package org.apache.poi.ss.util;
|
|
|
|
import java.util.Locale;
|
|
|
|
/**
|
|
* Contains specific examples of <tt>double</tt> values and their rendering in Excel.
|
|
*/
|
|
final class NumberToTextConversionExamples {
|
|
|
|
private NumberToTextConversionExamples() {
|
|
// no instances of this class
|
|
}
|
|
|
|
public static final class ExampleConversion {
|
|
private final String _javaRendering;
|
|
private final String _excelRendering;
|
|
private final double _doubleValue;
|
|
private final long _rawDoubleBits;
|
|
|
|
ExampleConversion(long rawDoubleBits, String javaRendering, String excelRendering) {
|
|
double d = Double.longBitsToDouble(rawDoubleBits);
|
|
if ("NaN".equals(javaRendering)) {
|
|
if (!Double.isNaN(d)) {
|
|
throw new IllegalArgumentException("value must be NaN");
|
|
}
|
|
} else {
|
|
if (Double.isNaN(d)) {
|
|
throw new IllegalArgumentException("value must not be NaN");
|
|
}
|
|
// just to be dead sure test conversion in java both ways
|
|
boolean javaToStringOk = javaRendering.equals(Double.toString(d));
|
|
boolean javaParseOk = Double.parseDouble(javaRendering) == d;
|
|
if(!javaToStringOk || !javaParseOk) {
|
|
String msgA = "Specified rawDoubleBits " + doubleToHexString(d) + " encodes to double '" + d + "'.";
|
|
String msgB = "Specified javaRendering '" + javaRendering+ "' parses as double with rawDoubleBits "
|
|
+ doubleToHexString(Double.parseDouble(javaRendering));
|
|
System.err.println(msgA);
|
|
System.err.println(msgB);
|
|
|
|
throw new RuntimeException(msgA + msgB);
|
|
}
|
|
}
|
|
_rawDoubleBits = rawDoubleBits;
|
|
_javaRendering = javaRendering;
|
|
_excelRendering = excelRendering;
|
|
_doubleValue = d;
|
|
}
|
|
private static String doubleToHexString(double d) {
|
|
return "0x" + Long.toHexString(Double.doubleToLongBits(d)).toUpperCase(Locale.ROOT) + "L";
|
|
}
|
|
public String getJavaRendering() {
|
|
return _javaRendering;
|
|
}
|
|
public String getExcelRendering() {
|
|
return _excelRendering;
|
|
}
|
|
public double getDoubleValue() {
|
|
return _doubleValue;
|
|
}
|
|
public boolean isNaN() {
|
|
return Double.isNaN(_doubleValue);
|
|
}
|
|
public long getRawDoubleBits() {
|
|
return _rawDoubleBits;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Number rendering examples as observed from Excel.
|
|
* TODO - some are currently disabled because POI does not pass these cases yet
|
|
*/
|
|
private static final ExampleConversion[] examples = {
|
|
|
|
// basic numbers
|
|
ec(0x0000000000000000L, "0.0", "0"),
|
|
ec(0x3FF0000000000000L, "1.0", "1"),
|
|
ec(0x3FF00068DB8BAC71L, "1.0001", "1.0001"),
|
|
ec(0x4087A00000000000L, "756.0", "756"),
|
|
ec(0x401E3D70A3D70A3DL, "7.56", "7.56"),
|
|
|
|
ec(0x405EDD3C07FB4C8CL, "123.4567890123455", "123.456789012345"),
|
|
ec(0x405EDD3C07FB4C99L, "123.45678901234568", "123.456789012346"),
|
|
ec(0x405EDD3C07FB4CAEL, "123.45678901234598", "123.456789012346"),
|
|
ec(0x4132D687E3DF2180L, "1234567.8901234567", "1234567.89012346"),
|
|
|
|
ec(0x3F543A272D9E0E49L, "0.001234567890123455", "0.00123456789012345"),
|
|
ec(0x3F543A272D9E0E4AL, "0.0012345678901234552", "0.00123456789012346"),
|
|
ec(0x3F543A272D9E0E55L, "0.0012345678901234576", "0.00123456789012346"),
|
|
ec(0x3F543A272D9E0E72L, "0.0012345678901234639", "0.00123456789012346"),
|
|
ec(0x3F543A272D9E0E76L, "0.0012345678901234647", "0.00123456789012346"),
|
|
ec(0x3F543A272D9E0E77L, "0.001234567890123465", "0.00123456789012346"),
|
|
|
|
ec(0x3F543A272D9E0E78L, "0.0012345678901234652", "0.00123456789012347"),
|
|
|
|
ec(0x3F543A272D9E0EA5L, "0.001234567890123475", "0.00123456789012347"),
|
|
ec(0x3F543A272D9E0EA6L, "0.0012345678901234751", "0.00123456789012348"),
|
|
|
|
|
|
ec(0x544CE6345CF3209CL, "1.2345678901234549E98", "1.23456789012345E+98"),
|
|
ec(0x544CE6345CF3209DL, "1.234567890123455E98", "1.23456789012346E+98"),
|
|
ec(0x544CE6345CF320DEL, "1.2345678901234649E98", "1.23456789012346E+98"),
|
|
ec(0x544CE6345CF320DFL, "1.234567890123465E98", "1.23456789012347E+98"),
|
|
ec(0x544CE6345CF32120L, "1.234567890123475E98", "1.23456789012347E+98"),
|
|
ec(0x544CE6345CF32121L, "1.2345678901234751E98", "1.23456789012348E+98"),
|
|
|
|
|
|
ec(0x54820FE0BA17F5E9L, "1.23456789012355E99", "1.2345678901236E+99"),
|
|
ec(0x54820FE0BA17F5EAL, "1.2345678901235502E99", "1.2345678901236E+99"),
|
|
ec(0x54820FE0BA17F784L, "1.2345678901236498E99", "1.2345678901237E+99"),
|
|
ec(0x54820FE0BA17F785L, "1.23456789012365E99", "1.2345678901237E+99"),
|
|
ec(0x54820FE0BA17F920L, "1.2345678901237498E99", "1.2345678901238E+99"),
|
|
ec(0x54820FE0BA17F921L, "1.23456789012375E99", "1.2345678901238E+99"),
|
|
|
|
|
|
// transitions around the E98,E99,E100 boundaries
|
|
ec(0x547D42AEA2879F19L,"9.999999999999974E98", "9.99999999999997E+98"),
|
|
ec(0x547D42AEA2879F1AL,"9.999999999999975E98", "9.99999999999998E+98"),
|
|
ec(0x547D42AEA2879F21L,"9.999999999999984E98", "9.99999999999998E+98"),
|
|
ec(0x547D42AEA2879F22L,"9.999999999999985E98", "9.99999999999999E+98"),
|
|
ec(0x547D42AEA2879F2AL,"9.999999999999995E98", "9.99999999999999E+98"),
|
|
ec(0x547D42AEA2879F2BL,"9.999999999999996E98", "1E+99"),
|
|
ec(0x547D42AEA287A0A0L,"1.0000000000000449E99", "1E+99"),
|
|
ec(0x547D42AEA287A0A1L,"1.000000000000045E99", "1.0000000000001E+99"),
|
|
ec(0x547D42AEA287A3D8L,"1.0000000000001449E99", "1.0000000000001E+99"),
|
|
ec(0x547D42AEA287A3D9L,"1.000000000000145E99", "1.0000000000002E+99"),
|
|
ec(0x547D42AEA287A710L,"1.000000000000245E99", "1.0000000000002E+99"),
|
|
ec(0x547D42AEA287A711L,"1.0000000000002451E99", "1.0000000000003E+99"),
|
|
|
|
|
|
ec(0x54B249AD2594C2F9L,"9.999999999999744E99", "9.9999999999997E+99"),
|
|
ec(0x54B249AD2594C2FAL,"9.999999999999746E99", "9.9999999999998E+99"),
|
|
ec(0x54B249AD2594C32DL,"9.999999999999845E99", "9.9999999999998E+99"),
|
|
ec(0x54B249AD2594C32EL,"9.999999999999847E99", "9.9999999999999E+99"),
|
|
ec(0x54B249AD2594C360L,"9.999999999999944E99", "9.9999999999999E+99"),
|
|
ec(0x54B249AD2594C361L,"9.999999999999946E99", "1E+100"),
|
|
ec(0x54B249AD2594C464L,"1.0000000000000449E100","1E+100"),
|
|
ec(0x54B249AD2594C465L,"1.000000000000045E100", "1.0000000000001E+100"),
|
|
ec(0x54B249AD2594C667L,"1.000000000000145E100", "1.0000000000001E+100"),
|
|
ec(0x54B249AD2594C668L,"1.0000000000001451E100","1.0000000000002E+100"),
|
|
ec(0x54B249AD2594C86AL,"1.000000000000245E100", "1.0000000000002E+100"),
|
|
ec(0x54B249AD2594C86BL,"1.0000000000002452E100","1.0000000000003E+100"),
|
|
|
|
|
|
ec(0x2B95DF5CA28EF4A8L,"1.0000000000000251E-98","1.00000000000003E-98"),
|
|
ec(0x2B95DF5CA28EF4A7L,"1.000000000000025E-98", "1.00000000000002E-98"),
|
|
ec(0x2B95DF5CA28EF46AL,"1.000000000000015E-98", "1.00000000000002E-98"),
|
|
ec(0x2B95DF5CA28EF469L,"1.0000000000000149E-98","1.00000000000001E-98"),
|
|
ec(0x2B95DF5CA28EF42DL,"1.0000000000000051E-98","1.00000000000001E-98"),
|
|
ec(0x2B95DF5CA28EF42CL,"1.000000000000005E-98", "1E-98"),
|
|
ec(0x2B95DF5CA28EF3ECL,"9.999999999999946E-99", "1E-98"),
|
|
ec(0x2B95DF5CA28EF3EBL,"9.999999999999944E-99", "9.9999999999999E-99"),
|
|
ec(0x2B95DF5CA28EF3AEL,"9.999999999999845E-99", "9.9999999999999E-99"),
|
|
ec(0x2B95DF5CA28EF3ADL,"9.999999999999843E-99", "9.9999999999998E-99"),
|
|
ec(0x2B95DF5CA28EF371L,"9.999999999999746E-99", "9.9999999999998E-99"),
|
|
ec(0x2B95DF5CA28EF370L,"9.999999999999744E-99", "9.9999999999997E-99"),
|
|
|
|
|
|
ec(0x2B617F7D4ED8C7F5L,"1.000000000000245E-99", "1.0000000000003E-99"),
|
|
ec(0x2B617F7D4ED8C7F4L,"1.0000000000002449E-99","1.0000000000002E-99"),
|
|
ec(0x2B617F7D4ED8C609L,"1.0000000000001452E-99","1.0000000000002E-99"),
|
|
ec(0x2B617F7D4ED8C608L,"1.000000000000145E-99", "1.0000000000001E-99"),
|
|
ec(0x2B617F7D4ED8C41CL,"1.000000000000045E-99", "1.0000000000001E-99"),
|
|
ec(0x2B617F7D4ED8C41BL,"1.0000000000000449E-99","1E-99"),
|
|
ec(0x2B617F7D4ED8C323L,"9.999999999999945E-100","1E-99"),
|
|
ec(0x2B617F7D4ED8C322L,"9.999999999999943E-100","9.9999999999999E-100"),
|
|
ec(0x2B617F7D4ED8C2F2L,"9.999999999999846E-100","9.9999999999999E-100"),
|
|
ec(0x2B617F7D4ED8C2F1L,"9.999999999999844E-100","9.9999999999998E-100"),
|
|
ec(0x2B617F7D4ED8C2C1L,"9.999999999999746E-100","9.9999999999998E-100"),
|
|
ec(0x2B617F7D4ED8C2C0L,"9.999999999999744E-100","9.9999999999997E-100"),
|
|
|
|
|
|
|
|
// small numbers
|
|
ec(0x3EE9E409302678BAL, "1.2345678901234568E-5", "1.23456789012346E-05"),
|
|
ec(0x3F202E85BE180B74L, "1.2345678901234567E-4", "0.000123456789012346"),
|
|
ec(0x3F543A272D9E0E51L, "0.0012345678901234567", "0.00123456789012346"),
|
|
ec(0x3F8948B0F90591E6L, "0.012345678901234568", "0.0123456789012346"),
|
|
|
|
ec(0x3EE9E409301B5A02L, "1.23456789E-5", "0.0000123456789"),
|
|
|
|
ec(0x3E6E7D05BDABDE50L, "5.6789012345E-8", "0.000000056789012345"),
|
|
ec(0x3E6E7D05BDAD407EL, "5.67890123456E-8", "5.67890123456E-08"),
|
|
ec(0x3E6E7D06029F18BEL, "5.678902E-8", "0.00000005678902"),
|
|
|
|
ec(0x2BCB5733CB32AE6EL, "9.999999999999123E-98", "9.99999999999912E-98"),
|
|
ec(0x2B617F7D4ED8C59EL, "1.0000000000001235E-99", "1.0000000000001E-99"),
|
|
ec(0x0036319916D67853L, "1.2345678901234578E-307", "1.2345678901235E-307"),
|
|
|
|
ec(0x359DEE7A4AD4B81FL, "2.0E-50", "2E-50"),
|
|
|
|
// large numbers
|
|
ec(0x41678C29DCD6E9E0L, "1.2345678901234567E7", "12345678.9012346"),
|
|
ec(0x42A674E79C5FE523L, "1.2345678901234568E13", "12345678901234.6"),
|
|
ec(0x42DC12218377DE6BL, "1.2345678901234567E14", "123456789012346"),
|
|
ec(0x43118B54F22AEB03L, "1.2345678901234568E15", "1234567890123460"),
|
|
ec(0x43E56A95319D63E1L, "1.2345678901234567E19", "12345678901234600000"),
|
|
ec(0x441AC53A7E04BCDAL, "1.2345678901234568E20", "1.23456789012346E+20"),
|
|
ec(0xC3E56A95319D63E1L, "-1.2345678901234567E19", "-12345678901234600000"),
|
|
ec(0xC41AC53A7E04BCDAL, "-1.2345678901234568E20", "-1.23456789012346E+20"),
|
|
|
|
ec(0x54820FE0BA17F46DL, "1.2345678901234577E99", "1.2345678901235E+99"),
|
|
ec(0x54B693D8E89DF188L, "1.2345678901234576E100", "1.2345678901235E+100"),
|
|
|
|
ec(0x4A611B0EC57E649AL, "2.0E50", "2E+50"),
|
|
|
|
// range extremities
|
|
ec(0x7FEFFFFFFFFFFFFFL, "1.7976931348623157E308", "1.7976931348623E+308"),
|
|
ec(0x0010000000000000L, "2.2250738585072014E-308", "2.2250738585072E-308"),
|
|
ec(0x000FFFFFFFFFFFFFL, "2.225073858507201E-308", "0"),
|
|
ec(0x0000000000000001L, "4.9E-324", "0"),
|
|
|
|
// infinity
|
|
ec(0x7FF0000000000000L, "Infinity", "1.7976931348623E+308"),
|
|
ec(0xFFF0000000000000L, "-Infinity", "1.7976931348623E+308"),
|
|
|
|
// shortening due to rounding
|
|
ec(0x441AC7A08EAD02F2L, "1.234999999999999E20", "1.235E+20"),
|
|
ec(0x40FE26BFFFFFFFF9L, "123499.9999999999", "123500"),
|
|
ec(0x3E4A857BFB2F2809L, "1.234999999999999E-8", "0.00000001235"),
|
|
ec(0x3BCD291DEF868C89L, "1.234999999999999E-20", "1.235E-20"),
|
|
|
|
// carry up due to rounding
|
|
// For clarity these tests choose values that don't round in java,
|
|
// but will round in excel. In some cases there is almost no difference
|
|
// between excel and java (e.g. 9.9..9E-8)
|
|
ec(0x444B1AE4D6E2EF4FL, "9.999999999999999E20", "1E+21"),
|
|
ec(0x412E847FFFFFFFFFL, "999999.9999999999", "1000000"),
|
|
ec(0x3E45798EE2308C39L, "9.999999999999999E-9", "0.00000001"),
|
|
ec(0x3C32725DD1D243ABL, "9.999999999999999E-19", "0.000000000000000001"),
|
|
ec(0x3BFD83C94FB6D2ABL, "9.999999999999999E-20", "1E-19"),
|
|
|
|
ec(0xC44B1AE4D6E2EF4FL, "-9.999999999999999E20", "-1E+21"),
|
|
ec(0xC12E847FFFFFFFFFL, "-999999.9999999999", "-1000000"),
|
|
ec(0xBE45798EE2308C39L, "-9.999999999999999E-9", "-0.00000001"),
|
|
ec(0xBC32725DD1D243ABL, "-9.999999999999999E-19", "-0.000000000000000001"),
|
|
ec(0xBBFD83C94FB6D2ABL, "-9.999999999999999E-20", "-1E-19"),
|
|
|
|
|
|
// NaNs
|
|
// Currently these test cases are not critical, since other limitations prevent any variety in
|
|
// or control of the bit patterns used to encode NaNs in evaluations.
|
|
ec(0xFFFF0420003C0000L, "NaN", "3.484840871308E+308"),
|
|
ec(0x7FF8000000000000L, "NaN", "2.6965397022935E+308"),
|
|
ec(0x7FFF0420003C0000L, "NaN", "3.484840871308E+308"),
|
|
ec(0xFFF8000000000000L, "NaN", "2.6965397022935E+308"),
|
|
ec(0xFFFF0AAAAAAAAAAAL, "NaN", "3.4877119413344E+308"),
|
|
ec(0x7FF80AAAAAAAAAAAL, "NaN", "2.7012211948322E+308"),
|
|
ec(0xFFFFFFFFFFFFFFFFL, "NaN", "3.5953862697246E+308"),
|
|
ec(0x7FFFFFFFFFFFFFFFL, "NaN", "3.5953862697246E+308"),
|
|
ec(0xFFF7FFFFFFFFFFFFL, "NaN", "2.6965397022935E+308"),
|
|
};
|
|
|
|
private static ExampleConversion ec(long rawDoubleBits, String javaRendering, String excelRendering) {
|
|
return new ExampleConversion(rawDoubleBits, javaRendering, excelRendering);
|
|
}
|
|
|
|
public static ExampleConversion[] getExampleConversions() {
|
|
return examples.clone();
|
|
}
|
|
}
|