size : 1968
uploaded_on : Tue Oct 27 00:00:00 1998
modified_on : Wed Dec 8 14:03:24 1999
title : Incorrect reals
org_filename : incorrectreal.txt
author : Earl F. Glynn
authoremail : EarlGlynn@WorldNet.att.net
description : Explanation about the limitations of the floating point represention of real numbers.
keywords : roundoff error
tested : not tested yet
submitted_by : Unofficial Delphi Developers FAQ
submitted_by_email : uddf@gnomehome.demon.nl
uploaded_by : nobody
modified_by : nobody
owner : nobody
lang : pas
file-type : text/plain
category : pascal-alg-maths
__END_OF_HEADER__
Incorrect Real values
From: "Earl F. Glynn"
>when i do a strtofloat on 1234.5544
>
>i get something like : 1234.55440000000003
>
>is there anyway to fix this because i think this is wrong!
Nothing is "wrong" here. This is just a limitation of floating-point numbers. The actual source of error is called roundoff error. This error is due to the fault of
floating-point arithmetic and to the fact that most decimal fractions become repeating fractions in the binary number system. Such numbers cannot be represented in a
finite number of bits. The word roundoff is not always accurate in this connection, and comes from the fact that many computers, when cutting off the last digits from
a number, "round" the number to its closest equivalent. Some computers do not round but merely cut off the last bits, with the resulting error still properly called
roundoff error (as opposed to truncation error, which is the term used when a series expansion is truncated). From Introduction to Numerical Methods, Peter A.
Stark, Macmillian Company, 1970.
Because of this "fuzz" with floating point numbers, comparison of two calculated floating point numbers should be based on either absolute or relative error. For
an absolute error comparison use something like:
IF ABS(CalculatedValue - TrueValue) < FuzzValue THEN ...,
where FuzzValue is application specific. For a relative error comparison use something like:
IF ABS( (CalculatedValue - TrueValue) / TrueValue ) <
AcceptableRelativeError THEN ...,
where AcceptableRelativeError is application specific (and obviously TrueValue <> 0.0).
The Delphi 3 math unit performs relative comparisons like this (but it's not exposed in the unit's interface):
FUNCTION RelSmall(X, Y: Extended): Boolean;
{ Returns True if X is small relative to Y }
CONST
C1: Double = 1E-15;
C2: Double = 1E-12;
BEGIN
Result := Abs(X) < (C1 + C2 * Abs(Y))
END;