Avatar billede Slettet bruger
17. april 2007 - 22:06 Der er 12 kommentarer og
1 løsning

Java regner forkert?

Nu har jeg sidder et par timer og forsøgt at hitte ud af, hvordan jeg løser mit problem - dette regnestykke skulle gerne give 0.95:
System.out.println("19.0 * 0.05 = " + (19.0 * 0.05));
Output: 19.0 * 0.05 = 0.9500000000000001

Nogen måder at komme ud over dette på en simpel måde?

/1
Avatar billede skcvg Nybegynder
17. april 2007 - 22:17 #1
Ja, sådan er det med afrunding. Men prøv med klassen java.math.BigDecimal - her kan du regne med mange betydende cifre.
Avatar billede arne_v Ekspert
17. april 2007 - 22:20 #2
egentligt ikke

saadan virker floating point i alle programmerings sprog

hvis du vil skjule det kan du udskrive med faerre decimaler

hvis du vil undgaa det skal du bruge en anden data type end double og float
Avatar billede roenving Novice
18. april 2007 - 03:31 #3
-- og man kan da tilføje, at i al praktisk regning er det nævnte resultat præcis 0,95, en afvigelse på 1 tusindedel billion kan ikke ses, selv ikke hvis man regner på USAs bruttonationalprodukt ...
Avatar billede roenving Novice
18. april 2007 - 04:33 #4
Hrm, det hedder vel 1 tusindbilliontedel ...

-- uden at vide præcis hvordan Javas måde at benytte floats er, kan det måske illustrere problematikken at kigge på binære repræsentationer af decimal-brøker:

0,95 =
1 * 0,5 +
1 * 0,25 +
1 * 0,125 +
1 * 0,0625 +
0 * 0,03125 +
0 * 0,015625 +
1 * 0,0078125 +
1 * 0,00390625 +
0 *

osv ...

-- det siger sig selv, at kun ganske få tal vil være repræsenteret fuldt nøjagtigt, derfor opererer man også med en meget høj grad af præcision i repræsentationens længde, ganske ofte 64 bit, som giver en præcision på ca. 15 betydende cifre, som dit eksempel også viser !-)
Avatar billede Slettet bruger
18. april 2007 - 08:06 #5
mht til BigDecimal, giver dokumentationen for denne constructor umiddelbart mistanke om at samme problem eksister for denne klasse:
http://java.sun.com/j2se/1.4/docs/api/java/math/BigDecimal.html#BigDecimal(double)

Løsningen blev en metode der afrunde og formatterer double med variabelt decimalantal.

private String formatDouble(double value, int decimals){
        if(decimals >= 0){
                double multiplier = Math.pow(10,decimals);
                int partResult = (int) (value*multiplier + 0.5);
                String output = "0.";
                for(int t = 0;t < decimals - Integer.toString(partResult).length();t++){
                        output += "0";
                }
                output += Integer.toString(partResult);
                return output;
        }else{
                return Integer.toString((int) value);
        }
}

Roenving>> Da du kom med en forklaring på problemet, får du point (læg et svar).

/1
Avatar billede mysitesolution Nybegynder
18. april 2007 - 08:20 #6
hhmm...

en float runder 1/3 op til 0,333334
og en double runder 1/3 ned til 0,3333333333333333
så der er lidt forskel.

Har kigget på netop dit regnestykke, og der viser en float det rigtige resultat, så hvis du kan overleve med floats så brug dem
Avatar billede Slettet bruger
18. april 2007 - 09:35 #7
Jeg skal kunne håndtere alle værdier, så det skal ikke kun virke med 0.95..
Men ellers tak for dit input..
Avatar billede arne_v Ekspert
18. april 2007 - 13:50 #8
der staar ogsaa i java docs at man altid boer bruge
  new BigDecimal("0.95")
og ikke
  new BigDecimal(0.95)
fordi at naar du laver en praecis BigDecimal udfra en upraecis double saa er du jo lige vidt
Avatar billede arne_v Ekspert
18. april 2007 - 13:51 #9
Med hensyn til paen konvertering til streng, saa ville jeg nok satse paa DecimalFormat
(eller printf hvis nyere Java)
Avatar billede arne_v Ekspert
21. juli 2007 - 16:29 #10
Tid at få afsluttet her ?
Avatar billede roenving Novice
22. juli 2007 - 03:09 #11
Hrm, måske på tide at give det helt runde 1-tal en chance for at lukke ...

Velbekomme '-)
Avatar billede Slettet bruger
22. juli 2007 - 15:18 #12
Tak tak..
Avatar billede roenving Novice
25. juli 2007 - 18:02 #13
-- og jeg takker for point ;~}
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