Если я пытаюсь воспроизвести программу на другом языке. Неразумно ли использовать большую точность?

Я нахожусь в процессе преобразования программы из кода Scilab в C++, и для меня важно сохранить результаты, полученные Scilab.

Я знаю, что Scilab использует двойную точность IEEE 754 и что удвоение C++ (хотя и не обязательно) реализовано аналогичным образом.

Не будет ли плохой идеей использовать более высокую точность (например, long double) в C++, если я пытаюсь точно сопоставить результаты Scilab?

Например: возможно ли, чтобы Scilab вычислил число равным 0,1234, тогда как в C++ с использованием длинных удвоений число будет равно 0,12345. Таким образом, потенциально может возникнуть расхождение, которое приведет к тому, что две программы будут давать разные результаты (хотя и более точные на C++).


person Paul Warnick    schedule 20.06.2016    source источник
comment
Готов поспорить, что вы никогда не получите точно идентичных результатов. Но вам это действительно нужно?   -  person Jesper Juhl    schedule 20.06.2016
comment
@JesperJuhl С технической точки зрения мне не нужны точные результаты. Проблема в том, что в моей программе много циклов, и если начальный цикл отклоняется даже на небольшую долю (а это так), конечная разница становится значительной.   -  person Paul Warnick    schedule 20.06.2016
comment
Если конечная разница значительна, не означает ли это, что ваша программа требует большей точности, чем позволяет встроенная плавающая точка?   -  person Galik    schedule 20.06.2016
comment
@Galik Не то чтобы я в курсе. Причина, по которой конечная разница становится значительной, заключается в начальной ошибке в сочетании с количеством вычислений, которым эта ошибка подвергается. Это означает, что если на первой итерации моей программы возникает ошибка 0,000000000001, эта разница усиливается по мере выполнения программы. Например, к 1000-й итерации эта ошибка стала равной 0,0001. Затем к 1 000 000-й итерации ошибка становится довольно большой.   -  person Paul Warnick    schedule 20.06.2016
comment
@Galik Это потому, что каждый шаг цикла зависит от значений, рассчитанных на предыдущем шаге. Поэтому ошибка становится все больше и больше по мере работы программы.   -  person Paul Warnick    schedule 20.06.2016
comment
Я понимаю, как ошибка накапливается, чтобы стать значительной. Я имею в виду, почему накопленная разница в одном блоке с плавающей запятой лучше, чем в другом? Похоже, вы просто предпочитаете неточности одного модуля с плавающей запятой другим.   -  person Galik    schedule 20.06.2016
comment
@Galik Ах, мой плохой. Я имею в виду, если бы результаты использования обычного двойника в C++ были идентичными (правильными). Было бы проблемой использовать длинный двойной? Это означает, может ли увеличение точности действительно вызвать проблему (потому что с меньшей точностью ответ будет правильным)?   -  person Paul Warnick    schedule 20.06.2016
comment
Как вы решили, что цифры Scilab верны? Вся цифровая математика с плавающей запятой фиксированного размера будет иметь ошибки. Чем больше число битов, тем меньше должны быть эти ошибки. Если переход к более высокой точности даст вам другие результаты, то, как мне кажется, это произошло из-за того, что ваш исходный расчет Scilab имеет значительные ошибки, которые не так значительны в расчете с более высокой точностью (при прочих равных условиях). Я хотел бы задаться вопросом, действительно ли исходные результаты Scilab были правильными или вы хотите воспроизвести тот же уровень ошибок, что и Scilab?   -  person Galik    schedule 20.06.2016
comment
@Galik На самом деле это то, что я пытаюсь сделать. Воспроизведите тот же уровень ошибок, что и код Scilab. И я полагаю, что это отвечает на мои вопросы. Поскольку код Scilab использует только двойную точность. Использование длинного двойника в C++ увеличило бы разницу между двумя программами.   -  person Paul Warnick    schedule 20.06.2016


Ответы (1)


Да, это вполне возможно.

Но поскольку числа с плавающей запятой никогда не бывают абсолютно точными, вы должны разработать свой алгоритм с учетом этого и постараться избежать того, чтобы эти «ошибки округления» испортили ваши вычисления через некоторое время.

Более того, как уже отмечалось в комментариях: не ожидайте, что ваша C++-программа выдаст те же результаты, что и программа Scilab, особенно если она так критична к небольшим изменениям. Вот почему большинство численных симуляций точны лишь до определенного предела, прежде чем они начнут давать «неправильные» результаты.

Чтобы дать вам несколько полезных советов, в C++ есть очень полезная опция typedefs. Используйте typedef, например typedef long double myFloatType, и используйте только myFloatType для своих вычислений (подумайте о лучшем имени, которое на самом деле говорит больше о том, для чего оно используется здесь!). Затем вы можете легко изменить его впоследствии, просто изменив одну строку кода и сравнив результаты.

Если разница значительна, возможно, стоит подумать о лучшем алгоритме.

person Anedar    schedule 20.06.2016