计算十进制值的双邻居

时间:2012-05-17 14:24:28

标签: java floating-point bigdecimal

代码:

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);
  }
}

输出:

0.1000000000000000055511151231257827021181583404541015625 0.6999999999999999555910790149937383830547332763671875

这很好,因为它让我找到最接近给定值的double。 但至于0.1,值越大,0.7值小于实际值。

如何获得任何十进制数的两个值(最近和最小)?

假设我从BigDecimal开始,然后将其转换为double,然后再转换为小数。我会得到更大或更小的价值。我怎么能得到另一个?

3 个答案:

答案 0 :(得分:2)

使用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"));
  }
}

打印输出:

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

答案 1 :(得分:1)

Math.ulp(double)方法可能对此有用,它返回的内容类似于给定值的可能浮点精度:

  

返回参数的ulp大小。双值的ulp是该浮点值与接下来幅度较大的双值之间的正距离。请注意,对于非NaN x,ulp(-x)== ulp(x)。

以下是一个例子:

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))));

答案 2 :(得分:0)

基于Integer或String创建BigDecimal:

// String:
BigDecimal a = new BigDecimal("0.1");

// Integer
BigDecimal b = (new BigDecimal(7)).movePointLeft(1);

它不会给你这样的结果。