Вывод чисел формата с плавающей запятой

Огромное спасибо разработчикам, что у нас есть возможность изучать Паскаль. Но есть вопрос. Рассмотрим программу демонстрирующую неточность хранения действительных чисел в формате с плавающей запятой.

int main()
{
    double a, b, c;
    a = 0.1;
    b = 0.2;
    c = 0.3;
    if(a + b == c)
        cout << "ok";
    else{
        cout << ":(";
        cout.precision(20);
        cout << "a = " << a << endl;
        cout << "b = " << b << endl;
        cout << "a + b = " << a + b << endl;
        cout << "c = " << c << endl;
    }
}

Данная программа хорошо показывает специфику работы с числами с плавающей запятой. Хотел своим школьникам показать на Паскале. И, хотя очевидно, что числа хранятся не точно, команда write никак не хочет это показать.

var a, b, c: double;
Begin
   a := 0.1;
   b := 0.2;
   c := 0.3;
   if a + b = c then
      write('ok')
   else begin
      writeLn(':(');
      writeLn('a = ', a:0:20);
      writeLn('b = ', b:0:20);
      writeLn('a + b = ', a + b:0:20);
      writeLn('c = ', c:0:20);
   end
End.

Можно ли как-то модифицировать программу, что бы команда write работала точно? Или очень хотелось бы узнать от авторов, как команда write на самом деле работает, какие идеи были заложены в её реализацию при выводе чисел в формате с плавающей запятой, что бы было понятно, почему это видно на С++, но не видно в Паскале.

Заранее огромное спасибо.

Мы пользуемся стандартным форматированием в платформе .NET Вот Ваш промер без write:

begin
  var r := 0.1+0.2;
  System.Console.WriteLine('{0,0:f20}',r);
  System.Console.WriteLine('{0,0:e20}',r);
  r := r - 0.3;
  System.Console.WriteLine('{0,0:f20}',r);
end.

Результат:

0,30000000000000000000
3,00000000000000040000e-001
0,00000000000000005551

Как видите, сумма выводится в точности 0.3, хотя при сложении возникает погрешность. Думаю, выводятся все значащие цифры, а остаток до 20-ти заполняется нулями. В случае вывода в экспоненциальном формате ваша погрешность уже появляется. Изменить это поведение мы не можем.

С другой стороны, чтобы проиллюстрировать погрешность Вы можете просто вывести разность a+b-c. Как видите, она будет равна

0,00000000000000005551

что и проиллюстрирует погрешность вычислений.

Спасибо.