Der genaue Wertebereich, in dessen Rahmen beim Rechnen mit Floats und Doubles korrekte Ergebnisse erzielt werden, sieht wie folgt aus:
Float: +- 1.175494e-38 bis +- 3.402823e+38
Double: +- 2.2250738585072013e-308 bis +- 1.7976931348623157e+308
D.h. man müsste bei Double auf Toleranzen von < 3e-308 kommen
Versuche ich, dass direkt berechnen zu lassen, d.h. ab wann eine 1 noch als 1 erkannt wird, kommt man nur auf etwa 1e-16.
genau 0.000 000 000 000 000 111 022 3025 ; ca. 1.11e-16
Wo liegt da das Problem? Übrigens die Methode, die Genauigkeit zu berechnen stammt als alten Fortran Codes als die
x87 Coprozessoren aufkamen.
Code: Alles auswählen
Procedure.d CalcDoublePrecision()
Protected.i I, N
Protected.d FPr, res
; IT CARRIES OUT AN APPROXIMATION OF MACHINE PRECISION
FPr = 1.0
N = 2
While (1.0 + FPR) > 1.0
FPr = 0.5 * FPr
; The For Next is only to confuse the copiler optimation
; especally for the C-Backend. It's to force the compiler
; to copy the FPr variable to the memory. Because the internal
; precision of floating Point registers might be higher.
; x32 and x64 (Floating Point calculation precision is 80 Bit)
; We need the precsion what can be saved in memory
; For I = 1 To N
; res = res + FPR * I
; Next
Wend
res + 1
ProcedureReturn FPr
EndProcedure
Procedure.i EQd(V1.d, V2.d, Tol.d) ; As Boolean
If Abs(V1 - V2) <= Tol
ProcedureReturn #True
EndIf
ProcedureReturn #False
EndProcedure
Debug CalcDoublePrecision()
Debug StrD(CalcDoublePrecision(),32)
#Tol = 0.0000000000000002
; 0.0000000000000001110223025 ; 1.11e-16
Define TOL.d = CalcDoublePrecision()
Define x.d = 1
;Define y1.d = 1.0000000000000001
Define y1.d = 1.0000000000000001
Define y2.d = 1.0000000000000002
Define y3.d = 1.0000000000000003
Define y4.d = 1.0000000000000004
Define y5.d = 1.0000000000000005
Debug Bool(EQd(x,y1,TOL))
Debug Bool(EQd(x,y2,TOL))
Debug Bool(EQd(x,y3,TOL))
Debug Bool(EQd(x,y4,TOL))
Debug Bool(EQd(x,y5,TOL))