Package org.apache.poi.ss.util
Class ExcelArithmetic
java.lang.Object
org.apache.poi.ss.util.ExcelArithmetic
Arithmetic helpers that reproduce how Excel computes with IEEE 754 doubles.
Excel stores and calculates in double precision, but only ever exposes 15 significant decimal digits, and it compensates for binary representation error in a few well-defined places. These helpers implement those places so that formula evaluation matches what a user sees in Excel.
- Since:
- 6.0.0
- See Also:
-
Method Summary
Modifier and TypeMethodDescriptionstatic doubleapproxAdd(double a, double b) Excel 97 and later compensate for the error introduced by converting decimal operands to binary when an addition or subtraction lands at or very close to zero: if the two magnitudes are equal to Excel (same 15 significant digits, seeNumberComparer), the result is exactly zero.static doubleapproxSub(double a, double b) static doubleapproxValue(double d) Returns the value as Excel sees it: rounded to 15 significant decimal digits.static BigDecimaltoBigDecimal(double d) Returns the value as Excel sees it, as an exact decimal: the 15 significant digits ofapproxValue(double), so that decimal arithmetic on it (rounding to a number of places, or to a multiple of a step) gives the answer Excel gives.static doubletruncate(double d) Truncates towards zero on the 15-digit view of the value, which is what Excel does with the non-integer arguments of QUOTIENT, GCD, LCM, FACT, FACTDOUBLE, COMBIN, ISEVEN, ISODD and friends ("if number is not an integer, it is truncated"):2.9999999999999996and-2.9999999999999996become 3 and -3,2.5becomes 2.
-
Method Details
-
approxValue
public static double approxValue(double d) Returns the value as Excel sees it: rounded to 15 significant decimal digits. Functions that truncate (INT, FLOOR, CEILING, MOD, ...) act on this view rather than on the raw binary value - e.g.INT(2490399.9999999995)is 2490400 in Excel. Integers and values with few fractional bits are exactly representable and are returned unchanged. -
toBigDecimal
Returns the value as Excel sees it, as an exact decimal: the 15 significant digits ofapproxValue(double), so that decimal arithmetic on it (rounding to a number of places, or to a multiple of a step) gives the answer Excel gives.0.1*3is0.3rather than0.30000000000000004, and2.675is exactly that rather than2.67499999999999982236431605997495353221893310546875.- Parameters:
d- a finite double- Throws:
NumberFormatException- if d is NaN or infinite- Since:
- 6.0.0
-
truncate
public static double truncate(double d) Truncates towards zero on the 15-digit view of the value, which is what Excel does with the non-integer arguments of QUOTIENT, GCD, LCM, FACT, FACTDOUBLE, COMBIN, ISEVEN, ISODD and friends ("if number is not an integer, it is truncated"):2.9999999999999996and-2.9999999999999996become 3 and -3,2.5becomes 2.- Returns:
- the truncated value as a double, so that magnitudes beyond the long range work
- Since:
- 6.0.0
- See Also:
-
approxAdd
public static double approxAdd(double a, double b) Excel 97 and later compensate for the error introduced by converting decimal operands to binary when an addition or subtraction lands at or very close to zero: if the two magnitudes are equal to Excel (same 15 significant digits, seeNumberComparer), the result is exactly zero.- Returns:
a + b, or exactly 0 when Excel would cancel the operands
-
approxSub
public static double approxSub(double a, double b) - Returns:
a - b, or exactly 0 when Excel would cancel the operands- See Also:
-