Ska datatypen Float eller Decimal användas för dollarbelopp?
Svaret är enkelt. Flyter aldrig. ALDRIG !
Floats var enligt IEEE 754 alltid binära, endast den nya standarden IEEE 754R definierade decimalformat. Många av de binära bråkdelarna kan aldrig vara lika med den exakta decimalrepresentationen.
Alla binära tal kan skrivas som m/2^n
(m
, n
positiva heltal), vilket decimaltal som helst som m/(2^n*5^n)
. Eftersom binärer saknar primtal factor 5
, alla binära tal kan representeras exakt med decimaler, men inte vice versa.
0.3 = 3/(2^1 * 5^1) = 0.3
0.3 = [0.25/0.5] [0.25/0.375] [0.25/3.125] [0.2825/3.125]
1/4 1/8 1/16 1/32
Så du får ett tal antingen högre eller lägre än det givna decimaltalet. Alltid.
Varför spelar det någon roll? Avrundning.
Normal avrundning betyder 0..4 ner, 5..9 upp. Så det gör spelar roll om resultatet är antingen 0.049999999999
.... eller 0.0500000000
... Du kanske vet att det betyder 5 cent, men datorn vet inte det och rundar 0.4999
... ner (fel) och 0.5000
... upp (höger).
Med tanke på att resultatet av flyttalsberäkningar alltid innehåller små feltermer är beslutet ren tur. Det blir hopplöst om du vill ha decimal avrundning till jämn hantering med binära tal.
Inte övertygad? Du insisterar på att allt är helt ok i ditt kontosystem? Tillgångar och skulder lika? Ok, ta sedan vart och ett av de givna formaterade talen för varje post, analysera dem och summera dem med ett oberoende decimalsystem!
Jämför det med den formaterade summan. Oj, det är något fel, eller hur?
För den beräkningen krävdes extrem noggrannhet och trohet (vi använde Oracles FLOAT) så att vi kunde registrera de "miljarddelar av ett öre" som samlades in.
Det hjälper inte mot detta fel. Eftersom alla människor automatiskt antar att datorn summerar rätt, och praktiskt taget ingen kontrollerar självständigt.