/ 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
Afrunding af en double til en decimal
Fra : Allan Bredahl


Dato : 13-12-00 17:05

Hej Alle


Jeg har dette : 0.1265464d

og vil afrunde til dette : 0.1





Hvilken metode skal der til for at gøre det ?



På forhånd tak


Allan Bredahl




 
 
Ulrik Magnusson (13-12-2000)
Kommentar
Fra : Ulrik Magnusson


Dato : 13-12-00 19:05

>
> Jeg har dette : 0.1265464d
> og vil afrunde til dette : 0.1
> Hvilken metode skal der til for at gøre det ?

Et forslag:

double d = 0.1265464d;
d = Math.floor(d * 10) / 10;

Ulrik Magnusson


Thomas Sejr Jensen (13-12-2000)
Kommentar
Fra : Thomas Sejr Jensen


Dato : 13-12-00 19:15

Gælder det ikke om at lave sin kode så indviklet som muligt??
"Ulrik Magnusson" <ulrikm@yahoo.com> skrev i en meddelelse
news:3A3836D1.1292CBB@yahoo.com...
> >
> > Jeg har dette : 0.1265464d
> > og vil afrunde til dette : 0.1
> > Hvilken metode skal der til for at gøre det ?
>
> Et forslag:
>
> double d = 0.1265464d;
> d = Math.floor(d * 10) / 10;
>
> Ulrik Magnusson
>



Ulrik Magnusson (13-12-2000)
Kommentar
Fra : Ulrik Magnusson


Dato : 13-12-00 19:28

> Gælder det ikke om at lave sin kode så indviklet som muligt??

Jo, det undskylder jeg meget.

double
d=0.1265464d
;
d= Math
.
floor
(
d
*10)/
10;

Ulrik Magnusson


Jesper Sørensen (14-12-2000)
Kommentar
Fra : Jesper Sørensen


Dato : 14-12-00 12:49

det burde vel være
double d = 0.1265464d;
d = Math.floor(d * 10+0.5) / 10;
^

for at det virker, din funktion vil altid runde ned.

JS
Ulrik Magnusson <ulrikm@yahoo.com> wrote in message
news:3A3836D1.1292CBB@yahoo.com...
> >
> > Jeg har dette : 0.1265464d
> > og vil afrunde til dette : 0.1
> > Hvilken metode skal der til for at gøre det ?
>
> Et forslag:
>
> double d = 0.1265464d;
> d = Math.floor(d * 10) / 10;
>
> Ulrik Magnusson
>



N/A (13-12-2000)
Kommentar
Fra : N/A


Dato : 13-12-00 19:52



Ulrik Magnusson (13-12-2000)
Kommentar
Fra : Ulrik Magnusson


Dato : 13-12-00 19:52

> Følgende virker
> double ny=(float) ( (int)(0.1265464*10) ) /10;
> Der kommer dog af en eller anden grund en masse decimaler med (er der nogen
> der kan forklare det?)

Næh, javac regner værdien ud (på compileringstidspunktet), så det er svært at
sige, hvad den har lavet (det må være en fejl). Det eneste bytecode, der
genereres er følgende:

0 ldc2_w #4 <Double 0.10000000149011612>
3 dstore_1

Generer bytecode for den kompilerede klasse K med:
javap -c K

Ulrik Magnusson


Troels Thomsen (13-12-2000)
Kommentar
Fra : Troels Thomsen


Dato : 13-12-00 22:26

> double ny=(float) ( (int)(0.1265464*10) ) /10;
> Det skal tilføjes at 0.19 også vil blive afrundet til 0.1, ikke 0.2.

Man kunne jo også afrunde :
double ny=(float) ( (int)(0.1265464*10+0.5) ) /10;


tpt



Lars Dam (14-12-2000)
Kommentar
Fra : Lars Dam


Dato : 14-12-00 09:30

On Wed, 13 Dec 2000 18:59:09 +0100, "Thomas Sejr Jensen"
<thomassj@worldonline.dk> wrote:

>Følgende virker
>double ny=(float) ( (int)(0.1265464*10) ) /10;
>
>Der kommer dog af en eller anden grund en masse decimaler med (er der nogen
>der kan forklare det?)

Den korte forklaring:

Det er fordi der kun er et begrænset antal bits til rådighed til
decimalerne - og derfor kan 'skæve' tal, når man snakker 'floating
points' ikke ramme et binært nul præcist; så nede på de yderste
decimaler kan floating point tal være upræcise.

Den lidt længere forklaring:

Decimal bits virker lige som alm. bits, de bliver bare halveret i
stedet for at fordoblet, når man 'tæller baglæns' i bit rækken:

i.e. ved en 4 bits decimal, vil de have værdierne:

1/2 1/4 1/8 1/16
0.5 0.25 0.125 0,0625

Ved 8 bits:

1/2 1/4 1/8 1/16 1/32 1/64 1/128 1/256
0.5 0.25 0.125 0,0625 0,03125 0,015625 0,0078125 0,00390625

Jo flere bits der er tilrådighed, jo større præcision.

Så for at repræsentere 0.1 binært, skal man sætte bits således at
brøkerne kommer så tæt på 0.1 som muligt - men hvis man kun har et
begrænset antal bits til rådighed - så kan man kun komme tæt på, og
ikke ramme præcist (med mindre 1/256 (for 8 bits præcision) går op i
den decimal man har)

Så for en 8 bits float bliver 0,1 lagret som:

0,1 ~= 1/16 + 1/32 + 1/256 (00010011 binært)
0,0625 + 0,03125 + 0,00390625 = 0,09765625

0,09765625 er altså tættest på 0,1, hvis man kun bruger 8 bits til
decimaler - det skal lige siges at dette regnestykke er hurtigt gjort
i hånden, så det er med forbehold for regnefejl; eksemplet belyser dog
problemet tilstrækkeligt.

For float vedkommende er der så vidt jeg ved ca. 40 bits til rådighed
for at repræsentere decimaler (af 64 bits) - double nok en 80 bits
præcision (af 128) - hvilket giver en langt højere præcision end 8
bits - derfor de flere decimaler (0.10000000149011612 jvnfr. anden
post i denne tråd)


Den helt præcise forklaring:

Kan i sikkert selv finde i et ieee dokument et eller andet sted.

vh. ld

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

Ulrik Magnusson (14-12-2000)
Kommentar
Fra : Ulrik Magnusson


Dato : 14-12-00 15:29

> Det er fordi der kun er et begrænset antal bits til rådighed til
> decimalerne - og derfor kan 'skæve' tal, når man snakker 'floating
> points' ikke ramme et binært nul præcist; så nede på de yderste
> decimaler kan floating point tal være upræcise.

Kan du så også forklare hvorfor

double ny = (double) ((int)(0.12*10)) /10;

giver 0.1 og

double ny = (float) ((int)(0.12*10)) /10;

giver 0.10000000149011612

??
(Begge regnes ud på compileringstidspunktet)
Ulrik Magnusson


Lars Dam (14-12-2000)
Kommentar
Fra : Lars Dam


Dato : 14-12-00 15:59

On Thu, 14 Dec 2000 14:28:37 GMT, Ulrik Magnusson <ulrikm@yahoo.com>
wrote:

>> Det er fordi der kun er et begrænset antal bits til rådighed til
>> decimalerne - og derfor kan 'skæve' tal, når man snakker 'floating
>> points' ikke ramme et binært nul præcist; så nede på de yderste
>> decimaler kan floating point tal være upræcise.
>
>Kan du så også forklare hvorfor
>
> double ny = (double) ((int)(0.12*10)) /10;
>
>giver 0.1 og

Sikkert fordi double har større præcision og kan ramme 0.1 præcist?

>
> double ny = (float) ((int)(0.12*10)) /10;
>
>giver 0.10000000149011612


Her caster du jo til en float, og ødelægger præcisionen og caster
tilbage - samme fejl, som hvis du castede en long (der har en større
værdi end max_int) tilbage til en int.

>
>??
>(Begge regnes ud på compileringstidspunktet)
>Ulrik Magnusson

vh. ld

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

Ulrik Magnusson (16-12-2000)
Kommentar
Fra : Ulrik Magnusson


Dato : 16-12-00 01:55

> >Kan du så også forklare hvorfor
> > double ny = (double) ((int)(0.12*10)) /10;
> >giver 0.1 og
> Sikkert fordi double har større præcision og kan ramme 0.1 præcist?
> > double ny = (float) ((int)(0.12*10)) /10;
> >giver 0.10000000149011612
> Her caster du jo til en float, og ødelægger præcisionen og caster
> tilbage - samme fejl, som hvis du castede en long (der har en større
> værdi end max_int) tilbage til en int.

Hvad så med:
float ny = (float) ((int)(0.12*10)) /10;
og
double ny = (double) ((int)(0.12*10)) /10;

som begge giver 0.1.

(Er pointen bare at man skal være forsigtig med flydende tal?)
Ulrik Magnusson


Lars Dam (18-12-2000)
Kommentar
Fra : Lars Dam


Dato : 18-12-00 12:28

On Sat, 16 Dec 2000 00:54:38 GMT, Ulrik Magnusson <ulrikm@yahoo.com>
wrote:

>> >Kan du så også forklare hvorfor
>> > double ny = (double) ((int)(0.12*10)) /10;
>> >giver 0.1 og
>> Sikkert fordi double har større præcision og kan ramme 0.1 præcist?
>> > double ny = (float) ((int)(0.12*10)) /10;
>> >giver 0.10000000149011612
>> Her caster du jo til en float, og ødelægger præcisionen og caster
>> tilbage - samme fejl, som hvis du castede en long (der har en større
>> værdi end max_int) tilbage til en int.
>
>Hvad så med:
>float ny = (float) ((int)(0.12*10)) /10;
>og
>double ny = (double) ((int)(0.12*10)) /10;
>
>som begge giver 0.1.

Umiddelbar kan jeg ikke lige give en fornuftig forklaring på det.

>(Er pointen bare at man skal være forsigtig med flydende tal?)

Ja - ihvertfald hvis du skal bruge rigtigt mange decimaler. Hvis ikke
du har brug for flere end den præcision der tilbydes er det ikke noget
problem - ud fra devisen om at hvis du skal bruge en præcision på e.g.
4 decimaler, så er 0.1000 det samme som 0.100000000006

>Ulrik Magnusson

vh. ld
--
"Time is the fire in which we burn"

Ulrik Magnusson (14-12-2000)
Kommentar
Fra : Ulrik Magnusson


Dato : 14-12-00 15:31

> Det er fordi der kun er et begrænset antal bits til rådighed til
> decimalerne - og derfor kan 'skæve' tal, når man snakker 'floating
> points' ikke ramme et binært nul præcist; så nede på de yderste
> decimaler kan floating point tal være upræcise.

Kan du så også forklare hvorfor

double ny = (double) ((int)(0.12*10)) /10;

giver 0.1 og

double ny = (float) ((int)(0.12*10)) /10;

giver 0.10000000149011612

??
(Begge regnes ud på compileringstidspunktet)
Ulrik Magnusson




Lars Dam (14-12-2000)
Kommentar
Fra : Lars Dam


Dato : 14-12-00 16:04

On Thu, 14 Dec 2000 14:31:21 GMT, Ulrik Magnusson <ulrikm@yahoo.com>
wrote:

>Kan du så også forklare hvorfor
>
> double ny = (double) ((int)(0.12*10)) /10;
>
>giver 0.1 og
>
> double ny = (float) ((int)(0.12*10)) /10;
>
>giver 0.10000000149011612
>
>??
>(Begge regnes ud på compileringstidspunktet)

Mit forrige svar gik på hvorfor du fik så mange decimaler - men jeg
blev lidt i tvivl om du spurgte hvorfor 0.12 kunne blive til 0.1 - det
er også ret simpelt:

Du gør: 0.12*10 = 1.2 - dette caster du så til en int, så bliver
decimalerne 0.2 fjernet og du får 1 - dernæst dividerer du med 10, og
får 0,1 som float - decimal unøjagtigheden finder du grunden til pga.
upræcisionen pga. for få decimal bits.

>Ulrik Magnusson

vh. ld
--
"Time is the fire in which we burn"

Søg
Reklame
Statistik
Spørgsmål : 177560
Tips : 31968
Nyheder : 719565
Indlæg : 6408941
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste