I am experiencing an unexpected result from the Trunc() function, due to the lack of precision of floating-point numbers, when the float value stored is just below the positive integer value:
var
u1, u2, u3, u4, u5, u6: double;
result1, result2: integer;
begin
{initialization of variables for a basic equation of which we take the integer part}
u1 := 4.0;
u2 := 2.5;
u3 := 0.05;
u4 := 0.1;
{first attempt with the equation as the argument of the Trunc() function}
result1 := Trunc(((u1 - u2) / 2 - u3) / u4); // *** unexpected and wrong result = 6
{second attempt with the intermediate result as the argument of the Trunc() function}
u5 := ((u1 - u2) / 2 - u3) / u4;
result2 := Trunc(u5); // *** right result = 7
{check: u6 = -4,16333634234434e-16 means that the equation returns 6.99999999...}
u6 := (((u1 - u2) / 2 - u3) / u4) - 7.0;
end;
How can this issue be properly managed?
Should the variable u5 here be rounded with the function System.Math.RoundTo() with argument ADigit = -15?
7so you can hard code it. But I guess that sounds silly, because you want to work with arbitrary values. In which case, I don't actually see that the answer is necessarily wrong, it's just a consequence of how floating point arithmetic works. What is the underlying mathematical problem?singlethe end result is not exactly 7 when debugging FPU progression of the calculation.((u1 - u2) / 2 - u3) / u4is computed at full (extended) precision. So, it's not double that is sanitized, it'sextendedthat rounds to nearestdouble.