Решил написать на Pascal свой вариант процедуры str, которая переводит число в строковое представление и при вводе str(12.5:9:3, s) занесет в переменную s строку " 12.500" длиной 9 символов с 3-мя символами после запятой и 3-мя пробелами вначале.
Так вот, при написании процедуры, ответственной за перевод в строковое представление части числа после запятой, возникла проблема.
program Example;
function
FracPart(n: real): real;
begin
if n - round(n) >= 0 then
FracPart := n - round(n)
else
FracPart := 1 + n - round(n)
end;
function
IntPart(n:real): integer;
begin
if n - round(n) >= 0 then
IntPart := round(n)
else
IntPart := round(n) - 1
end;
function
IntToChr(n: shortint): char;
begin
IntToChr := chr(n + 48)
end;
var
n: real;
b,i: byte;
s2: string;
begin
writeln('Enter a number');
readln(n);
writeln('Enter a number of digits after the point');
readln(b);
n := FracPart(n);
s2 := '';
if n = 0 then
begin
if b > 0 then
begin
s2 := '.';
for i := 1 to b do
begin
s2 := s2 + '0';
end
end
end
else
begin
if b > 0 then
begin
s2 := '.';
for i := 1 to b do
begin
s2 := s2 + IntToChr(IntPart(n * 10));
n := FracPart(n * 10)
end
end
end;
writeln(s2)
end.
При b=3 и n равном 5.5 или 5.4 программа выдает корректные ответы .500 и .400. Однако при b=3 и n равном 5.6 или 5.3 программа выдает ошибки вида .599 и .299.
Насколько я понял, ошибка происходит в подпрограмме IntPart, ответственной за выделение целой части дробного числа. В определенной ситуации я ожидаю, что в условии if значение n - round(n) будет 0, а на практике, из-за погрешности вычислений типа real, значением будет -0,00000000001. Из-за этого оператор ветвления отработает не так, как я изначально этого ожидал.
Как устранить влияние погрешности при вычислениях с использованием типа Real в этой и в других моих будущих программах?