Calculation of double decimal neighbors

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

Output:

0.1000000000000000055511151231257827021181583404541015625 0.6999999999999999555910790149937383830547332763671875

This is good because it allows me to find doublewhich is closest to the given value. But as for 0.1, the value is greater, and the value is 0.7less than the real value.

How can I get both values ​​(nearest closest and closest) for any decimal?

Suppose I start with BigDecimal, and then convert it to double, and then back to decimal. I will get more or less. How could I get another?

+1
source share
3 answers

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
source

Math.ulp(double) , - :

ulp . Ulp - , . , non-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))));
+1

Create a BigDecimal based on Integer or String:

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

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

This will not give you such results.

0
source

All Articles