"René Holdgard Wilhardt" wrote:
> Hej.
>
> Hvis jeg laver denne her:
>
> double d = 4.1;
> double rest = d % 1;
>
> Så ville jeg mene at rest = 0.1
>
> Men jeg får dette resultat:
> 0.09999999999999964
>
> Hvorfor ?
Hermed et forsøg på en lidt mere uddybende forklaring:
% operatoren defineres på følgende måde (kun essensen) i Java Language
Specification:
(
http://java.sun.com/docs/books/jls/first_edition/html/15.doc.html#239829)
    "the floating-point remainder r from the
    division of a dividend n by a divisor d is defined by the
    mathematical relation r = n-d*q where q is an integer [...]
    whose magnitude is as large as possible without
    exceeding the magnitude of the true mathematical quotient of
    n and d."
    vi får så (q=4):
   4.1 % 1 =  4.1 - 1 * 4  =  4.1 - 4
4.1-4 defineres så til at skulle give et IEEE 754 resultat
(
http://java.sun.com/docs/books/jls/first_edition/html/4.doc.html#9249)
- and the plot thickens:
I IEEE 754 repræsenteres double værdier som 1 fortegnsbit, 11
eksponentbits og 52 'betydende' bits.
Værdien af et flydende tal er så defineret til at være
((-1)^fortegn) * (1+betydende) * (2^(eksponent-1023))
De betydende regnes ud fra venstre mod højre som en sum af
negative 2-potenser. Eks.
101 = 2^-1 + 2^-3,
001 = 2^-3 og
011 = 2^-2 + 2^-3
Hvis vi så i stedet for 52 betydende bits bruger 3, bliver den nærmeste
representation af 0.1 følgende mønster:
sign:     eksponent:         betydende:
0         01111111011       011
Dette er dog ikke 0.1 men 0.859375, da
    ((-1)^0))   //fortegn
    *  (1 + (0*2^-1)  +  (1*2^-2)  +  (1*2^-3))  // betydende
    *  (2^(1019-1023))  // eksponent
= 1 * (1.375) * (0.625)
= 0.859375
0.1 vil altså altid blive representeret som 0.859375 med 3 betydende
bits.
Situationen med 52 betydende bits er den samme - man skal bare fælde en
regnskov for at regne den ud i hånden.
Ulrik Magnusson