正在运行的示例非常容易理解:
program Project1;
uses
SysUtils, Math;
var
fValue: double;
fValueMax: double;
begin
fValue := 7.0207503445953527;
fValueMax := Max(0, fValue);
writeln(fValue);
writeln(fValueMax);
readln;
end.
但是结果完全出乎意料。由于某些原因,Max函数不仅会从两个参数返回较大的数字,还会更改其值。
在上面的示例代码中,fValueMax的期望值正好是fValue,但是fValueMax更大。差异大约为E-7,虽然很小,但仍然出乎意料,这使我的以下代码崩溃(此处未发布该代码,以使问题更清楚和简单)。
答案 0 :(得分:10)
我应该预先声明,我上次使用Pascal的时间接近25年前。但是出于好奇,我取消了Free Pascal并尝试了以下方法:
program Project1;
uses
SysUtils, Math;
var
fValue: double;
fValueMax: double;
fSingle: single;
fValue2: double;
fValue2b: double;
fValueMax2: double;
begin
fValue := 7.0207503445953527;
fSingle := 7.0207503445953527;
fValueMax := Max(0, fValue);
writeln(fValue); // prints 7.0207503445953527E+000
writeln(fValueMax); // prints 7.0207505226135254E+000
writeln(fSingle); // prints 7.020750523E+00
fValue2 := 7.0207503445953527;
fValue2b := 0.0;
fValueMax2 := Max(fValue2b, fValue2);
writeln(fValue2); // prints 7.0207503445953527E+000
writeln(fValueMax2); // prints 7.0207503445953527E+000
readln;
end.
我的前两个writeln
命令显示的结果与您报告看到的结果相同。我怀疑也许Max
返回的值的精度低于您希望返回的double
的精度,所以我创建了fSingle
并将其分配给您与分配给{{1 }},当然,它的值看起来与您在fValue
中返回的值非常接近。
因此,最后,我没有使用fValueMax
和文字Max
来调用fValue
,而是使用了两个0
类型的变量来调用它,其中一个已设置为double
。在这种情况下,您可以看到输入(0.0
)和输出(fValue2
)具有完全相同的值。因此,尽管我不确切知道用于确定要调用的重载的Pascal规则是什么,但我不知道您最初对fValueMax2
的调用是否以某种方式解析为采用两个Max
值并返回相同值的版本
尽管您可能知道这一点,但我还是不得不提起通常的警告,如single
和single
这样的浮点类型将无法始终准确地代表您的值希望他们这样做。 Here's a good overview.