1

Well Hard to explain, but here it is. In java code, I use a double number,but this number get very small number at the end that I don't want. Maybe I need to use a better way to get the remainning.

Here's the code:

public class MyClass {
  public static void main(String args[]) {
            String vRetour = "";
    Boolean valeurTrouve = false;
           double chiffre = .08 ;
    double valeurTravailDouble = 0;
    long vIntegerPart = 0;

    while (! valeurTrouve) {
        for (int i = 0; i<101;i++) {
            valeurTravailDouble = chiffre * 8;
            vIntegerPart = (long) valeurTravailDouble;

            vRetour = vRetour + vIntegerPart;
            if ((valeurTravailDouble - vIntegerPart) == 0) {
                valeurTrouve = true;
                break;
            }
            chiffre = (valeurTravailDouble - vIntegerPart);
                    System.out.println(i + " = " + chiffre);
        }
    }
}

}

The problem is at the end, I have remaning undesired number like on line 1 , I have a 1 at the end. After on line 2 I have a 9. But this number increase and increase give me a bad at the line 17 because he increase to be part of my number.

  • 0 = 0.64
  • 1 = 0.1200000000000001
  • 2 = 0.9600000000000009
  • 3 = 0.6800000000000068
  • 4 = 0.44000000000005457
  • 5 = 0.5200000000004366
  • 6 = 0.16000000000349246
  • 7 = 0.2800000000279397
  • 8 = 0.24000000022351742
  • 9 = 0.9200000017881393
  • 10 = 0.36000001430511475
  • 11 = 0.880000114440918
  • 12 = 0.04000091552734375
  • 13 = 0.32000732421875
  • 14 = 0.56005859375
  • 15 = 0.48046875
  • 16 = 0.84375
  • 17 = 0.75

What's wrong, How I can deal with double without keeping the end of the number ?

baronming
  • 210
  • 1
  • 3
  • 19

3 Answers3

0

Java is known not to be able to "add" properly. You should try rounding your numbers and limiting decimal spaces earlier on in your code to prevent the errors. Use import java.math.BigDecimal to do your rounding before you finish your calculations.

For how to round check out this other post: Java BigDecimal: Round to the nearest whole value

Edward Dan
  • 134
  • 1
  • 10
0

It's not a problem of Java. It's problem of hardware representation of floating point numbers in computers in general. Java is just not "hiding" this fact from you.

The representation has two parts. Mantisa and exponent.

FP number is then represented as M * 2 ^ E.

Now imagine number 0.1 in this representation, limited to 3 bits (2 + sign). With that minimum fragment to represent is 2^-3 which is 0.128. So an attempt to represent 0.1 ends up by getting 0.128. with computers the precission is much bigger, put stil limited. So you can get much smaller difference.

To justify bigger difference, now imagine 0.1*10 converted to "our representation with 4 bit exponent, we get 0.128*10 = 1.28 !

This is in general issue with FP numbers in computers. That's why it's not recomended e.g. to compare FP numbers using a == b

Ondřej Fischer
  • 411
  • 1
  • 7
  • 16
0

here's the working code:

   while (! valeurTrouve) {
        for (int i = 0; i<101;i++) {
            valeurTravailDouble = java.math.BigDecimal.valueOf(chiffre * 8).setScale(5, java.math.RoundingMode.HALF_UP).doubleValue();
                        System.out.println(i + " :: " + valeurTravailDouble);
            vIntegerPart = (int) valeurTravailDouble;

            vRetour = vRetour + vIntegerPart;

            if ((valeurTravailDouble - vIntegerPart) == 0) {
                valeurTrouve = true;
                break;
            }
            chiffre = java.math.BigDecimal.valueOf((valeurTravailDouble - vIntegerPart)).setScale(5, java.math.RoundingMode.HALF_UP).doubleValue();
                    System.out.println(i + " = " + chiffre);
        }
    }

I use a Precision of 5, but maybe I had to use 3.

baronming
  • 210
  • 1
  • 3
  • 19