开发者

Java rounding issues

开发者 https://www.devze.com 2023-03-04 22:17 出处:网络
I am using the following code to round the float value which is given as input. But i cant get it right. If i give $80 i should get $80.00 and if i give $40.009889 i should get $40.01. How do i do thi

I am using the following code to round the float value which is given as input. But i cant get it right. If i give $80 i should get $80.00 and if i give $40.009889 i should get $40.01. How do i do this ?

public class round {
public static float round_this(float num) {
    //float num = 2.954165f;
    float round = Round(num,2);
    return round;
  }
  private static float Round(float Rval开发者_StackOverflow中文版, int Rpl) {
  float p = (float)Math.pow(10,Rpl);
  Rval = Rval * p;
  float tmp = Math.round(Rval);
  return (float)tmp/p;
    }
}


This is why you don't use floats for money, because you get stuck in this game of 'Garbage In, Data Out'. Use java.math.BigDecimal instead. BigDecimal lets you specify a fixed-decimal value that isn't subject to representation problems.

(When I say don't use floats that includes doubles, it's the same issue.)

Here's an example. I create two BigDecimal numbers. For the first one I use the constructor that takes a floating-point number. For the first one I use the constructor that takes a string. In both cases the BigDecimal shows me what the number is that it holds:

groovy:000> f = new BigDecimal(1.01)
===> 1.0100000000000000088817841970012523233890533447265625
groovy:000> d = new BigDecimal("1.01")
===> 1.01

See this question for more explanation, also there's another question with a good answer here.


From The Floating-Point Guide:

Why don’t my numbers, like 0.1 + 0.2 add up to a nice round 0.3, and instead I get a weird result like 0.30000000000000004?

Because internally, computers use a format (binary floating-point) that cannot accurately represent a number like 0.1, 0.2 or 0.3 at all.

When the code is compiled or interpreted, your “0.1” is already rounded to the nearest number in that format, which results in a small rounding error even before the calculation happens.


Use BigDecimal class instead of float.

And use Java code like this:

BigDecimal bd = new BigDecimal(floatVal);
bd = bd.setScale(2, BigDecimal.ROUND_HALF_UP);


I wouldn't use float, I suggest using double or int or long or (if you have to) BigDecimal

private static final long[] TENS = new long[19];
static {
    TENS[0] = 1;
    for (int i = 1; i < TENS.length; i++) TENS[i] = TENS[i - 1] * 10;
}
public static double round(double x, int precision) {
    long tens = TENS[precision];
    long unscaled = (long) (x < 0 ? x * tens - 0.5 : x * tens + 0.5);
    return (double) unscaled / tens;
}

This does not give a precise answer for all fractions as that is not possible with floating point, however it will give you an answer which will print correctly.

double num = 2.954165;
double round = round(num, 2);
System.out.println(round);

prints

2.95


This would do it.

 public static void main(String[] args) {
    double d = 12.349678;
    int r = (int) Math.round(d*100);
    double f = r / 100.0;
   System.out.println(f);
 }

You can short this method, it's easy to understand that's why I have written like this

0

精彩评论

暂无评论...
验证码 换一张
取 消