08. september 2004 - 00:51Der er
10 kommentarer og 2 løsninger
Fejl i double udregning?
Jeg har to double vaerdier:
double min = -2.34269; double max = 2.342691;
Jeg finder midt punktet:
double med = (min + max) / 2;
Jeg ville nu regne med at med ville vaere 0.000005 men det er den ikke, den er istedet 0.0000004955481815233 eller noget i den retning. Det tyder jo paa for faa bit, men der staar i dok at den er praecis optil 15 - 16 bit....
Ups, i min post, der skrev jeg 15 - 16 bit... det var forkert. Det er 15 - 16 decimal
Jeg tror ikke det har noget med det at goere, eftersom der er flere end min computer paa arbejdet der har samme problem.
Vaerdien er helt praecist:
0.00000049999999984784438
Som man kan se, er det faktisk ude paa det 15 - 16 decimal det gaar galt, saa det er rigtigt hvad de skriver. Jeg kan bare ikke se hvad mine to vaerdier har med saa mange decimaler at goere....?????????????!!!!!!!!!!!!!!1
Excel viser kun 0.0000005 fordi du ikke har valgt nok decimaler jeg kan også få excel til at vise 4,99999999847844000000000E-07
Problemet er at "uendeligt" mange tal skal skrives som X antal bit (x=32 eller x=64 x=128 alt efter type). Det gør at ikke alle tal kan skrives helt præsist. I en computer er der er ikke et binært tal for hver tal i virkeligheden. Det som styre det er væriden af det mindst betydne bit (LSB).
For lige at bygge lidt videre på noget af det der allerede er skrevet.
en floating point (float og double i C#) er gemt som:
2^a * (1 + b1/2 + b2/4 + b3/8 + ...)
det betyder at ikke bare kan ikke alle tal repræsenteres eksakt men at det er meget sjældent at decimaler kan repræsenteres eksakt da det bruges 1/2, 1/4, 1/8 etc. og ikke 1/10, 1/100, 1/100 etc..
Floating point er beregnet til fysiske størrelser med naturlig usikkerhed.
Jeg har 45 km til arbejde. Jeg har ikke 44.99999732 km til arbejde, fordi det giver ingen mening at angive den afstand med den præcision.
Beløb og lignende skal normalt angives eksakt.
Derfor er der døds straf for at bruge floating point (float og double i C#) til beløb.
Løsningen er det som hedder fixed point. Som er en eksakt data type med et fast antal decimaler. Den er decimalt orienteret ikke binært orienteret og kan repræsentere alle værdier indenfor range med det antal decimaler. I sin mest primitive form gemmer man bare en integer og antal decimaler således at 123 og 2 betyder 1.23 !
C# har indbygget en data type for det som hedder decimal.
Og jeg ville skrive decimal versionen som:
decimal min = -2.34269m; decimal max = 2.342691m; decimal med = (min + max) / 2;
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.