/ Forside / Teknologi / Udvikling / Java / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
Java
#NavnPoint
molokyle 3688
Klaudi 855
strarup 740
Forvirret 660
gøgeungen 500
Teil 373
Stouenberg 360
vnc 360
pmbruun 341
10  mccracken 320
Forkerte dicimaler
Fra : Martin Ehmsen


Dato : 20-02-01 10:54

Hej derude...
Jeg har et meget underligt problem, med mit java program. Pointen er at
det skal indlaese nogle tal fra en fil og udskrive gennemsnittet. Det
goer jeg ved at laese alle tal og laegge dem sammen, samtidig med at jeg
laeser antallet af tal (meget lige til, let program). Jeg faar ogsaa den
rigtige sum og det rigtige antal tal; men naar jeg laver divisionen af
disse to tal og udskriver det, saa faar jeg noget som er helt hen i
vejret. Nemlig at 128.3 delt med 5 er 25.660000000000004
Jeg har vedlagt java-filen, samt den fil som jeg laeser ind fra, samt
det output jeg faar fra koerslen paa min (RedHat 7.0 kernel 2.4.1 med
jdk1.3). Det giver i oevrigt samme resultat naar jeg koere det pa en
anden linux box.
Jeg savner en forklaring...

Mvh Thames


=====Projekt.java=====

import java.io.*;

public class Projekt
{
public static void main( String[] args )
{
final String FIL_NAVN = "taldata";
String line;
double value, sum = 0.0;
int antaltal = 0, antallinier = 0;

try {
FileReader fr = new FileReader( FIL_NAVN );
BufferedReader inFile = new BufferedReader( fr );
while( (line = inFile.readLine()) != null ) {
antallinier++;
try {
value = Double.parseDouble( line );
System.out.println( value );
sum += value;
antaltal++;
}
catch( NumberFormatException exception ) {
System.out.println( "Linie " + antallinier + " er
ikke et korrekt tal!" );
}
}
inFile.close();
System.out.println( "Summen er: " + sum );
System.out.println( "Antal tal er: " + antaltal );
if( antaltal != 0 ) {
System.out.println( "Gennemsnittet er: " + (sum /
antaltal) );
}
else
System.out.println( "Umuligt at beregne et gennemsnit.
Indtast nogle tal!" );
}

catch( FileNotFoundException exception ) {
System.out.println( "Filen " + FIL_NAVN + " eksistere
tilsyneladende ikke!" );
}

catch( IOException exception ) {
System.out.println( "Der opstod foelgende fejl under
laesningen af filen " + FIL_NAVN + ":" + exception);
}
}
}

=====taldata=====

7.1
6.0
2.0
100.7
bent
12.5

=====Output fra en koersel=====

7.1
6.0
2.0
100.7
Linie 5 er ikke et tal!
12.5
Summen er: 128.3
Antal tal er: 5
Gennemsnittet er: 25.660000000000004

 
 
Allan Unnerup (20-02-2001)
Kommentar
Fra : Allan Unnerup


Dato : 20-02-01 11:45


>Jeg har et meget underligt problem, med mit java program. Pointen er at
>det skal indlaese nogle tal fra en fil og udskrive gennemsnittet. Det
>goer jeg ved at laese alle tal og laegge dem sammen, samtidig med at jeg
>laeser antallet af tal (meget lige til, let program). Jeg faar ogsaa den
>rigtige sum og det rigtige antal tal; men naar jeg laver divisionen af
>disse to tal og udskriver det, saa faar jeg noget som er helt hen i
>vejret. Nemlig at 128.3 delt med 5 er 25.660000000000004

>Jeg savner en forklaring...

Det ser da meget fornuftigt ud. Når du regner med tal, der ikke kan
repræsenteres præcist i det binære talsystem, vil du få en lille fejl på det
sidste ciffer. Det kan ikke være anderledes.

Det svarer lidt til, at du skal skrive tallet 17, men kun må benytte lige
tal. Så bliver du nødt til enten at skrive 16 eller 18, altså får du en fejl
på sidste ciffer.

Hilsen Allan



Martin Ehmsen (20-02-2001)
Kommentar
Fra : Martin Ehmsen


Dato : 20-02-01 11:55

Allan Unnerup wrote:
> Det ser da meget fornuftigt ud. Når du regner med tal, der ikke kan
> repræsenteres præcist i det binære talsystem, vil du få en lille fejl på det
> sidste ciffer. Det kan ikke være anderledes.
>
> Det svarer lidt til, at du skal skrive tallet 17, men kun må benytte lige
> tal. Så bliver du nødt til enten at skrive 16 eller 18, altså får du en fejl
> på sidste ciffer.

Kan du saa ikke forklare mig, hvorfor min lommeregner kan regne 128.3
delt med 5 ud, og stadig give det rigtige svar: 25.66
Bruger den da ikke det binaere talsystem.
Hvis man kan faa en lommeregner til det, hvorfor kan java saa ikke???
Det virker altsaa totalt taabeligt paa mig.
Det sjove er at programmet giver det rigtige svar ved andre vaerdier
(ogsaa decimalbroeker).

Thames

Dennis Thrysøe (20-02-2001)
Kommentar
Fra : Dennis Thrysøe


Dato : 20-02-01 12:26



Martin Ehmsen wrote:

> Allan Unnerup wrote:
>
>> Det ser da meget fornuftigt ud. Når du regner med tal, der ikke kan
>> repræsenteres præcist i det binære talsystem, vil du få en lille fejl på det
>> sidste ciffer. Det kan ikke være anderledes.
>>
>> Det svarer lidt til, at du skal skrive tallet 17, men kun må benytte lige
>> tal. Så bliver du nødt til enten at skrive 16 eller 18, altså får du en fejl
>> på sidste ciffer.
>
>
> Kan du saa ikke forklare mig, hvorfor min lommeregner kan regne 128.3
> delt med 5 ud, og stadig give det rigtige svar: 25.66
> Bruger den da ikke det binaere talsystem.
> Hvis man kan faa en lommeregner til det, hvorfor kan java saa ikke???
> Det virker altsaa totalt taabeligt paa mig.
> Det sjove er at programmet giver det rigtige svar ved andre vaerdier
> (ogsaa decimalbroeker).

Måske lommeregneren udregner et ekstra decimal, som ikke vises?

-dennis


Allan Unnerup (20-02-2001)
Kommentar
Fra : Allan Unnerup


Dato : 20-02-01 16:57


>Kan du saa ikke forklare mig, hvorfor min lommeregner kan regne 128.3
>delt med 5 ud, og stadig give det rigtige svar: 25.66

Nu bevæger vi os vist lidt uden for Java, men jeg vil tro, at der i
vejledningen til din lommeregner står hvilken præcision den regner med. Den
vil givetvis være større end de 10? cifre, der vises på din lommeregner.

Hilsen Allan




Bertel Lund Hansen (20-02-2001)
Kommentar
Fra : Bertel Lund Hansen


Dato : 20-02-01 18:16

Martin Ehmsen skrev:

>Hvis man kan faa en lommeregner til det, hvorfor kan java saa ikke?

Det er ikke Javas skyld. Ethvert programmeringssprog vil løbe ind
i tilsvarende problemer, og det er fundamentalt for computere (og
lommeregnere) med et begrænset antal cifre.

Det er banalt at man ikke kan stole på en test som:
   if (værdi==0) ...
hvis værdi er af typen double (eller en anden float-type).

Det er vel muligt at skære de sidste decimaler af? Så bliver
resultatet 'rigtigt'.

>Det sjove er at programmet giver det rigtige svar ved andre vaerdier
>(ogsaa decimalbroeker).

Ikke ved *alle* andre beregninger.

--
Bertel   http://lundhansen.dk/bertel/
   FIDUSO: http://fiduso.dk/

Esben Mose Hansen (24-02-2001)
Kommentar
Fra : Esben Mose Hansen


Dato : 24-02-01 10:45

Martin Ehmsen wrote:

> Allan Unnerup wrote:
>
>
> Kan du saa ikke forklare mig, hvorfor min lommeregner kan regne 128.3
> delt med 5 ud, og stadig give det rigtige svar: 25.66
> Bruger den da ikke det binaere talsystem.
> Hvis man kan faa en lommeregner til det, hvorfor kan java saa ikke???
> Det virker altsaa totalt taabeligt paa mig.
>
Som andre har skrevet, arbejder næsten alle lommeregnere med 3 skjulte
cifre. Men det er ikke forklaringen her. Problemet er at du forsøger at
regne med decimaltal som beinære tal, hvilket generelt er en dårlig idé,
med mindre hastighed er vigtigere end præcision. Istedet bør du finde en
klasse der kan regne med decimaltal. Det der undrer mig er at jeg ikke
kunne finde en sådan indbygget i java. Kan det virkeligt passe?

Nej det kan ej. Klassen hedder java.math.BigDecimal Scale er hvor
mange decimaler der skal være efter kommaet. Husk at sætte den til noget
fornuftigt.

mvh. Esben


Peter Hagstrøm (20-02-2001)
Kommentar
Fra : Peter Hagstrøm


Dato : 20-02-01 18:38


"Martin Ehmsen" <ehmsen@imada.sdu.dk> wrote in message
news:3A923ECB.12F648E9@imada.sdu.dk...
> Hej derude...
> Jeg har et meget underligt problem, med mit java program. Pointen er at
> det skal indlaese nogle tal fra en fil og udskrive gennemsnittet. Det
> goer jeg ved at laese alle tal og laegge dem sammen, samtidig med at jeg
> laeser antallet af tal (meget lige til, let program). Jeg faar ogsaa den
> rigtige sum og det rigtige antal tal; men naar jeg laver divisionen af
> disse to tal og udskriver det, saa faar jeg noget som er helt hen i
> vejret. Nemlig at 128.3 delt med 5 er 25.660000000000004

Grunden er, at det er svært at repræsentere komma tal i et tal system
der ikke har komma tal. Løsning kan, i det her tilfælde, være at mindske
præcisionen. I stedet for at bruge double, så bruge en float:

Følgende kode:
/* CODE */
public static void main( String args[] ) {
float floatnumber = (float)128.3;
double doublenumber = 128.3;

System.out.println( "Float number:" + floatnumber/5 );
System.out.println( "Double number:" + doublenumber/5 );
}
/* END CODE */

giver på mit system (win2k) følgende resultat:

Float number:25.66
Double number:25.660000000000004

Det kan godt virke lidt paradoxalt men float kan nogen gange være
god at bruge til sådant et formål.

Hvis det kun er for syns skyld, kan du jo også køre den igennem
DecimalFormat klassen eller lign.

> Jeg har vedlagt java-filen, samt den fil som jeg laeser ind fra, samt
> det output jeg faar fra koerslen paa min (RedHat 7.0 kernel 2.4.1 med
> jdk1.3). Det giver i oevrigt samme resultat naar jeg koere det pa en
> anden linux box.
> Jeg savner en forklaring...




Lars Dam (21-02-2001)
Kommentar
Fra : Lars Dam


Dato : 21-02-01 09:54

On Tue, 20 Feb 2001 10:54:19 +0100, Martin Ehmsen
<ehmsen@imada.sdu.dk> wrote:

>Hej derude...
>Jeg har et meget underligt problem, med mit java program. Pointen er at

Det er ikke så underligt...

>det skal indlaese nogle tal fra en fil og udskrive gennemsnittet. Det
>goer jeg ved at laese alle tal og laegge dem sammen, samtidig med at jeg
>laeser antallet af tal (meget lige til, let program). Jeg faar ogsaa den
>rigtige sum og det rigtige antal tal; men naar jeg laver divisionen af
>disse to tal og udskriver det, saa faar jeg noget som er helt hen i
>vejret. Nemlig at 128.3 delt med 5 er 25.660000000000004

Se en forklaring jeg skrev for nogen tid siden:

http://groups.google.com/groups?q=lars+%2Bdam+decimal&hl=en&lr=&safe=off&rnum=1&seld=952127246&ic=1

vh. ld

--
"Time is the fire in which we burn"

Carsten Sørensen (21-02-2001)
Kommentar
Fra : Carsten Sørensen


Dato : 21-02-01 12:08

"Lars Dam" <lars_simple_spam_protection_dam@post2.tele.dk> wrote in message
news:5f079to1lif7oktd4n691l885c4e4tgunm@4ax.com...
> Se en forklaring jeg skrev for nogen tid siden:
>
>
http://groups.google.com/groups?q=lars+%2Bdam+decimal&hl=en&lr=&safe=off&rnu
m=1&seld=952127246&ic=1

Kort bemærkning til en udmærket forklaring:

float er 32 bits (1 tegn, 8 eksponent, 23 mantisse [effektivt er det 24 når
man tæller det implicitte ettal])
double er 64 (1, 11, 52[53])


Carsten Sørensen




Søg
Reklame
Statistik
Spørgsmål : 177501
Tips : 31968
Nyheder : 719565
Indlæg : 6408527
Brugere : 218887

Månedens bedste
Årets bedste
Sidste års bedste