Неожиданный результат функции Max в FreePascal

Пример запуска очень прост для понимания:

program Project1;

uses
SysUtils, Math;

var
  fValue: double;
  fValueMax: double;
begin
  fValue := 7.0207503445953527;
  fValueMax := Max(0, fValue);
  writeln(fValue);
  writeln(fValueMax);
  readln;
end.   

Однако результат совершенно неожиданный. По какой-то причине программа Project1 ; использует 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 ); // печатает 7.0207503445953527E + 000 writeln ( fValueMax ); // печатает 7.0207505226135254E + 000 writeln ( fSingle ); // печатает 7.020750523E + 00 fValue2 : = 7.0207503445953527 ; fValue2b : = 0.0 ; fValueMax2 : = Max ( fValue2b , fValue2 ); writeln ( fValue2 ); // печатает 7.0207503445953527E + 000 writeln ( fValueMax2 ); // печатает 7.0207503445953527E + 000 readln ; конец . функция не только возвращает большее число из двух аргументов, но и изменяет ее значение.

В приведенном выше примере код ожидаемое значение writelnMax точно удваивается, но вместо этого fSingle больше. Разница примерно равна E-7, такая маленькая, но все же неожиданная и сбивает мой следующий код (который здесь не публикуется, чтобы вопрос был ясным и простым).

delphi,freepascal,

2

Ответов: 1


10 принят

Я должен сказать, что последний раз, когда я использовал Паскаля, был близок к 25 годам ранее. Но я вытащил Free Pascal из любопытства и попробовал это:

fValueMax

Мои первые две Maxкоманды показывают тот же результат, о котором вы сообщали о просмотре. Я подозревал, что, возможно, fValueвозвращал ценность с меньшей точностью, которую 0вы ожидали вернуться, поэтому я создал doubleи присвоил ей тот же самый литерал, который вы назначили fValue, и, конечно же, его значение выглядит очень близко к тому, что вы возвращаетесь в fValueMax,

Таким образом , в конце концов, вместо того , чтобы вызывать Maxс fValueи буквальным 0, я назвал его с двумя переменными типа 0.0, один из которых я установил в fValue2. В этом случае вы можете видеть, что input ( fValueMax2) и output ( Max) имеют точно такое же значение. Поэтому, хотя я не знаю точно, какие правила Pascal предназначены для определения перегрузки для вызова, мне интересно, был ли ваш первоначальный вызов Maxкаким-то образом разрешающим версию, которая принимает два singleзначения и возвращает то же самое.

Хотя вы можете быть в курсе этого, я чувствую себя вынужденным бросить в обычное предостережение о том, как типы с плавающей точкой, например, singleи doubleне всегда смогут точно представлять значения, которые вы им хотите. Вот хороший обзор.

Дельфы, FreePascal,
Похожие вопросы