问题
The code:
import java.math.*;
public class x
{
public static void main(String[] args)
{
BigDecimal a = new BigDecimal(0.1);
BigDecimal b = new BigDecimal(0.7);
System.out.println(a);
System.out.println(b);
}
}
The output:
0.1000000000000000055511151231257827021181583404541015625
0.6999999999999999555910790149937383830547332763671875
This is nice because it lets me find a double
that is the closest to given value.
But as for 0.1
a value is bigger and for 0.7
value is smaller than real value.
How can I get both values (closest bigger and closest smaller) for any decimal number?
Assume I start with BigDecimal
, then convert it do a double
and then back to decimal. I'll get bigger or smaller value. How could I got the other?
回答1:
Use nextAfter(double start, double direction):
import java.math.*;
public class a
{
public static void printNeighbours(BigDecimal start)
{
double result1 = start.doubleValue();
double result2;
BigDecimal r1 = new BigDecimal(result1);
int com = start.compareTo(r1);
if(com != 0)
result2 = Math.nextAfter(result1, com * Double.MAX_VALUE);
else
{
result2 = Math.nextAfter(result1, Double.MAX_VALUE);
result1 = Math.nextAfter(result1, -Double.MAX_VALUE);
r1 = new BigDecimal(result1);
}
BigDecimal r2 = new BigDecimal(result2);
System.out.println("starting:\t"+start);
if(com<0)
{
System.out.println("smaller:\t" + r2);
System.out.println("bigger:\t\t"+r1);
}
else
{
System.out.println("smaller:\t" + r1);
System.out.println("bigger:\t\t"+r2);
}
System.out.println();
}
public static void main(String[] args)
{
printNeighbours(new BigDecimal("0.25"));
printNeighbours(new BigDecimal("0.1"));
printNeighbours(new BigDecimal("0.7"));
}
}
Printout:
starting: 0.25
smaller: 0.2499999999999999722444243843710864894092082977294921875
bigger: 0.250000000000000055511151231257827021181583404541015625
starting: 0.1
smaller: 0.09999999999999999167332731531132594682276248931884765625
bigger: 0.1000000000000000055511151231257827021181583404541015625
starting: 0.7
smaller: 0.6999999999999999555910790149937383830547332763671875
bigger: 0.70000000000000006661338147750939242541790008544921875
回答2:
The Math.ulp(double) method might be useful for this, it returns something like the possible floating point precision for the given value:
Returns the size of an ulp of the argument. An ulp of a double value is the positive distance between this floating-point value and the double value next larger in magnitude. Note that for non-NaN x, ulp(-x) == ulp(x).
Here is an example:
System.out.println(new BigDecimal(0.1).subtract(new BigDecimal(Math.ulp(0.1))));
System.out.println(new BigDecimal(0.7).add(new BigDecimal(Math.ulp(0.7))));
回答3:
Create BigDecimal based on Integer or on String:
// String:
BigDecimal a = new BigDecimal("0.1");
// Integer
BigDecimal b = (new BigDecimal(7)).movePointLeft(1);
It will not give you such results.
来源:https://stackoverflow.com/questions/10637594/calculating-double-neighbours-of-a-decimal-value