Avatar billede fredand Forsker
11. oktober 2006 - 16:22 Der er 10 kommentarer og
1 løsning

How to get a nice round on a real?

Hello!

Sometimes i get a very large decimal-part of a double when I do some opretaions.

In this example i Think I do like:
double d = 1400;
double multiplier = 0.001;
d = d * m;

Then I do d = d / m;

Hard to explain why I do al this...

...how ever I think I would get 1.4. But I get 1.4000000000000001.

Is there a nice solution to get the correct number that is 1.4 in this example??

Best regards
Fredrik
Avatar billede arne_v Ekspert
11. oktober 2006 - 16:28 #1
if this is scientific data then the usage of double is correct and the
result is also "correct"

if this is money data then the usage of double is wrong and you should be
using BigDecimal instead and you will get 1.4 then

this is the nature of floating point

(as a 99% sure workaround you can print with a 3 decimals)
Avatar billede fredand Forsker
11. oktober 2006 - 20:38 #2
Hello!

Thanks for your reply! It really helped me out!

package mathtester;

import java.math.*;

public class MathTester
{
    public MathTester()
    {
        double d = 1.4;
        double multiplier1 = 0.000001;
        double multiplier2 = 0.0001;
        d = d * multiplier1;
        d = d / multiplier2;
        System.out.println(d);

        int decimalPlace = 2;

        BigDecimal bigDecimal = new BigDecimal(d);
        bigDecimal = bigDecimal.setScale(decimalPlace ,BigDecimal.ROUND_HALF_UP);
        d = bigDecimal.doubleValue();
        System.out.println(d);


    }

    public static void main(String[] args)
    {
        new MathTester();
    }
}

Please give a svar so I can reward yiu mate!

Best regards
Fredrik
Avatar billede arne_v Ekspert
11. oktober 2006 - 21:26 #3
I was actually thinking about:

        BigDecimal xd = new BigDecimal("1.4");
        BigDecimal xmultiplier1 = new BigDecimal("0.000001");
        BigDecimal xmultiplier2 = new BigDecimal("0.0001");
        xd = xd.multiply(xmultiplier1);
        xd = xd.divide(xmultiplier2);
        System.out.println(xd);
Avatar billede arne_v Ekspert
11. oktober 2006 - 21:26 #4
It is worth noting that DECIMAL/NUMERIC is part of all databases and that C# actually
has decimal as a simple data type
Avatar billede arne_v Ekspert
11. oktober 2006 - 21:27 #5
svar
Avatar billede fredand Forsker
12. oktober 2006 - 12:44 #6
Hello!

I'm just able to use 1.4 so I guess I need to use:

        BigDecimal bigDecimal = new BigDecimal(d);
        bigDecimal = bigDecimal.setScale(decimalPlace ,BigDecimal.ROUND_HALF_UP);
        d = bigDecimal.doubleValue();
Best regards
Fredrik
Avatar billede arne_v Ekspert
12. oktober 2006 - 13:39 #7
21:26:03 should work in almost any Java version
Avatar billede fredand Forsker
19. oktober 2006 - 16:49 #8
Hello!

Perhaps I could ask you.

Would we have the same problem if we used float instead of double?

We have tried with som long float numbers but all those calculations seems to work fine.

Perhaps we just were lucky?

Best regards
Fredrik
Avatar billede arne_v Ekspert
19. oktober 2006 - 17:54 #9
float and double share the same characteristics

they just have different precision

you can see the same effect for floats, but probably for other numbers
Avatar billede pondo Nybegynder
03. november 2006 - 11:04 #10
When i hit this issue i usually get around it in a "noobish" kind of way, but it still works.
Ex:
If i get the double 14.50006 and only want 2 digits ill just multiply with 100 and parse to integer and then back to double:

double d = 14.50006*100;
int i = Integer.parseInt(d);
d = i/100;

Just wanted to mention this little shortcut
Avatar billede arne_v Ekspert
03. november 2006 - 23:04 #11
I assume that you mean:

        double d = 14.50006*100;
        int i = (int)d;
        d = i/100.0;

because what posted does really not work.

That is an OK solution if you want to round well within the precision of floating
point.

It does not really solve the precision problem.

And as a side note:

x = ((int)(x * 100))/100.0;

always round down - there is a relative good probability that

x = ((int)(x * 100 + 0.5))/100.0;

which rounds to nearest is better
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester