public final class DecimalFunctions extends Static
float and double values while taking in account their representation in base 10.
Methods in this class may be helpful when used after parsing or before formatting a number in base 10:
floatToDouble(float) and deltaForDoubleToDecimal(double):
fractionDigitsForValue(double) and
fractionDigitsForDelta(double, boolean):
MathFunctions.pow10(int),
Math.log10(double)Defined in the sis-utility module
| Modifier and Type | Method and Description |
|---|---|
static double |
deltaForDoubleToDecimal(double value)
Returns the difference between the given
double value and the representation of that value in base 10. |
static double |
floatToDouble(float value)
Converts the given
float value to a double with the extra decimal fraction digits
set to zero. |
static int |
fractionDigitsForDelta(double accuracy,
boolean strict)
Returns the number of fraction digits needed for formatting in base 10 numbers of the given
accuracy.
|
static int |
fractionDigitsForValue(double value)
Returns the number of significant fraction digits when formatting the given number in base 10.
|
static int |
fractionDigitsForValue(double value,
int uncertainDigits)
Returns the number of significant fraction digits, potentially minus trailing digits that may be rounding error.
|
public static double floatToDouble(float value)
float value to a double with the extra decimal fraction digits
set to zero. This is different than the standard cast in the Java language, which set the extra binary
fraction digits to zero.
For example (double) 0.1f gives 0.10000000149011612 while floatToDouble(0.1f) returns 0.1.
Float.parseFloat(String) (directly or indirectly), and if that call can not be replaced by a call to
Double.parseDouble(String) (for example because the original String is not available anymore),
then this method may be useful if one consider the String representation in base 10 as definitive.
But if the value come from an instrument measurement or a calculation, then there is probably no reason to use
this method because base 10 is not more "real" than base 2 or any other base for natural phenomenon.return Double.parseDouble(Float.toString(value));
value - the float value to convert as a double.double with the extra decimal fraction digits set to zero.public static double deltaForDoubleToDecimal(double value)
double value and the representation of that value in base 10.
For any value in the method's domain of validity (defined below), this method is approximatively
equivalent to the following code except that it is potentially faster since the actual implementation
avoids the creation of BigDecimal objects:
BigDecimal base2 = new BigDecimal(value); // Exact same value as stored in IEEE 754 format. BigDecimal base10 = BigDecimal.valueOf(value); // Exact same value as shown by println(value). return base10.subtract(base2).doubleValue();Computing
value + deltaForDoubleToDecimal(value) has no effect since the absolute value of the
returned delta is always smaller than Math.ulp(value) / 2.
To see an effect, a type with more precision than the double type is necessary.
abs(value) < 3E-8 approximatively,
except for the 0 value which is supported. For any non-zero value closer to zero than the 3E-8
threshold, this method returns NaN because of insufficient algorithm accuracy.
This limitation may change in any future SIS version if we find a better algorithm.value - the value for which to get the delta compared to its base 10 representation.double value for getting a result
closer to its base 10 representation, or NaN if it can not be computed.public static int fractionDigitsForDelta(double accuracy,
boolean strict)
strict argument is true, then for any given accuracy
this method returns a value n such as the difference between adjacent numbers
formatted in base 10 with n fraction digits will always be equal or smaller
than accuracy. Examples:
fractionDigitsForDelta(0.001, true) returns 3.fractionDigitsForDelta(0.009, true) returns 3.fractionDigitsForDelta(0.010, true) returns 2.fractionDigitsForDelta(0.099, true) returns 3 (special case).Special cases:
accuracy is NaN or infinity, then this method returns 0
since those values are not represented by decimal digits.accuracy is 0, then this method returns 324 since 10-324 is the first power of 10
smaller than the minimal strictly positive double value (4.9E-324).
double value is guaranteed to be rounded to exactly 0 no matter what the
next fraction digits are.accuracy is greater than 1, then this method returns
the number of "unnecessary" trailing zeros as a negative number.
fractionDigitsForDelta(100, …) returns -2.accuracy are equal or greater than 95
(e.g. 0.00099) and the strict argument is true, then this method
increases the number of needed fraction digits in order to prevent the rounded
number to be collapsed into the next integer value.
accuracy is 0.95, then a return value of 1 is not sufficient since
the rounded value of 0.95 with 1 fraction digit would be 1.0. Such value would be a
violation of this method contract since the difference between 0 and that formatted
value would be greater than the accuracy. Note that this is not an artificial rule;
this is related to the fact that 0.9999… is mathematically strictly equals to 1.(int)
-floor(log10(accuracy))
except for the 0, NaN, infinities and 0.…95 special cases.accuracy - the desired accuracy of numbers to format in base 10.strict - true for checking the 0.…95 special case.
If false, then the difference between adjacent formatted numbers is not
guaranteed to be smaller than accuracy in every cases.NumberFormat.setMaximumFractionDigits(int)public static int fractionDigitsForValue(double value)
fractionDigitsForValue(1.0) returns 16,
because the double format can store almost 16 decimal digits after 1.
fractionDigitsForDelta(Math.ulp(value), false), except that it is
potentially faster.
Special cases:
value is NaN or infinity, then this method returns 0
since those values are not represented by decimal digits.value is 0, then this method returns 324 since
Math.ulp(0) = 4.9E-324.NumberFormat for formatting all significant digits of a
double value, padding with trailing zeros if necessary, but no more than necessary.value - the value for which to get the number of significant fraction digits.value is NaN or infinity.NumberFormat.setMinimumFractionDigits(int)public static int fractionDigitsForValue(double value,
int uncertainDigits)
fractionDigitsForValue(double). Then there
is a choice:
value to an amount of fraction digits given by (fractionDigits
- uncertainDigits) the 4 last fraction digits before the rounded ones are zero, then this method
returns fractionDigits - uncertainDigits.fractionDigits.fractionDigitsForValue(179.12499999999824) returns 14,
the amount of digits after the decimal separator.fractionDigitsForValue(179.12499999999824, 3) returns 11 because rounding the 3 last digits
(i.e. rounding after the 11th digit) results in 179.125000000000.
Since the 4 last fraction digits are zero, the condition for allowing that rounding is meet.fractionDigitsForValue(179.12499999999824, 2) returns 14 because rounding the 2 last digits
(i.e. rounding after the 12th digit) results in 179.124999999998.
The condition for 4 trailing zero fraction digits is not meet.fractionDigitsForValue(179.12499997999999, 3) returns 14 because rounding the 3 last digits
results in 179.12499997000. The condition for 4 trailing zero fraction digits is not meet.value - the value for which to get the number of significant fraction fraction digits minus rounding error.uncertainDigits - number of trailing fraction digits which may be rounding error artefacts.value is NaN or infinity.Copyright © 2010–2017 The Apache Software Foundation. All rights reserved.