2016-06-07 4 views
2

Примечание: Я использовал тег Matlab на всякий случай, если они поддерживают ту же точность. (Из того, что я могу сказать, обе программы очень похожи.)Какова точность вычислений с плавающей запятой в Scilab?

В качестве продолжения предыдущего вопроса (here), я пытаюсь определить уровень точности, который мне нужно установить (в C++, которую я сейчас конвертирую из кода Scilab) в порядке mock точность программы Scilab. По сути, обе программы с продуктом одинаковые (или очень похожие на).

При вычислении расчета с плавающей запятой в Scilab, какой уровень точности поддерживается?

Я прочитал (here и несколько других мест), которые при работе с арифметикой с плавающей точкой в ​​C++ двойные могут поддерживать только где-то около 16 знаков после запятой точно, например:

 4 8 12 16 
    v v v v 
0.947368421052631578 long double 
0.947368421052631526 double 

Как аналогична ли эта точность по сравнению с Scilab?

+0

Это не совсем корректную оценить плавающей точечной ошибки в «десятичных разрядах». Что относительно 1.999999999999999999999999999 и 2.0? Они различаются во всех десятичных знаках. Ошибка зависит от * целого * числа не только десятичной части. – Suever

+0

@Suever Это хороший момент. Как вы оцениваете их? –

+0

Это действительно зависит от того, что вы пытаетесь сделать. Вы пытаетесь определить правильный тип данных для использования? – Suever

ответ

3

Re-проводки комментарий в ответ:

IEEE 754 числа двойной точности с плавающей точкой стандартное представление в наиболее распространенных языках, как MATLAB, C++ и SciLab:

https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0ahUKEwiajY7LzZbNAhWJix4KHcrEA1wQFgggMAA&url=http%3A%2F%2Fforge.scilab.org%2Findex.php%2Fp%2Fdocscifloat%2Fdownloads%2Fget%2Ffloatingpoint_v0.2.pdf&usg=AFQjCNFQiOVdgkjuxhFXhp1PwDFY-J-Qbg&sig2=vH0cpadZqi0bNqa9F0Gmig&cad=rja

так Я не ожидаю, что вам нужно будет сделать что-то особенное для представления точности, кроме использования удвоений C++ (если только ваш SciLab-код не использует высокоточные поплавки).

Обратите внимание, что представления двух различных IEEE 754 совместимых реализаций могут различаться после 16 значащих цифр:

MATLAB:

>> fprintf('%1.30f\n',1/2342317.0) 
0.000000426927695952341190000000 

Python:

>> "%1.30f" % (1/2342317,) 
'0.000000426927695952341193713560' 
+0

Последнее замечание в вашем ответе - это то, что меня достает. Является ли этот язык конкретным? Смысл, будут ли цифры после 16 цифр одинаковыми для конкретного расчета каждый раз, когда вы запускаете расчет, если вы используете один и тот же язык? Кроме того, если после 16 цифр цифры могут быть разными. Как мне перевести программу с одного языка (Scilab) на другой (C++), сохраняя тот же результат? Есть ли способ усечения чисел, так что используются только первые 16 цифр (при этом вычисления одинаковы)? –

+1

Не зависит от конкретного языка, но зависит от платформы/языка, да. Поэтому, если я запустил вышеуказанный оператор в MATLAB 2015b в Windows, я получаю одинаковые «лишние цифры» каждый раз. Тем не менее, мне не гарантированы те же «дополнительные цифры», если я переключусь на MATLAB на Linux или даже на другую версию MATLAB. – gariepy

+1

Но дело в том, почему вы беспокоитесь о «лишних цифрах»? Они не настоящие. Если у вас есть приложение, которое на самом деле использует более 16 значащих цифр (и для реальных проблем это очень редко), тогда вам нужно использовать одну из высокоточных математических библиотек, которые имеют наиболее распространенные языки в качестве расширений. Но просто попытка сопоставить произвольные цифры от одной реализации к другой - это, ну, бессмысленное усилие. – gariepy

2

Каждый общий язык (стандартный C++, scilab, matlab, ...) использует в том же формате для представления десятичных чисел. Это известно как IEEE754 и его точная документация объясняется:

https://en.wikipedia.org/wiki/Double-precision_floating-point_format

Это означает, что точность остается постоянным почти все часто используемые системы. Это номер , близкий к 2^-52 (или, что то же самое, 2.2204e-16). Он определяет «расстояние от 1.0 до следующего наибольшего числа двойной точности».

Когда вы используете scilab, вы можете подтвердить это командой %epshttps://help.scilab.org/docs/5.5.1/fr_FR/percenteps.html. Для matlab он хранится в переменной epshttp://nl.mathworks.com/help/matlab/ref/eps.html. Для C++ это немного сложнее (см .: http://en.cppreference.com/w/cpp/types/numeric_limits/epsilon).

Итак, не беспокойтесь о точности , если вы не используете конкретную машину (атипичные архитектуры или очень старые компьютеры или высокоточные десятичные знаки (64 бит). Стандартные по умолчанию всегда будут соответствовать одному стандарту (IEEE 754).

Но, не забывайте, даже если он кажется постоянным, что ошибка может быть неодинаковой между очень большими числами и очень малой (система рассчитана на максимальную точность для интервала [0, 1 [и для интервала [1, MAXIMUM [)).

Это может быть показано в следующем примере:

>>> 1e100 == 1e100+1 
True 
>>> 1 == 2 
False 

Чтобы убедиться, что ваш код переносит на разных языках, я предлагаю вам явно относится к функциям, которые дают точность станка. Например, в scipy: print(np.finfo(float).eps). Но, как правило, хорошо спроектированные алгоритмы не будут сильно отличаться на машине с несколько разными эпсилонцами.

Например, если я реализую петлю для чего-то, что имеет тенденцию будет быть 0 (asymptoticly), в MATLAB, я должен написать:

while(val < eps) do 
... 
end 

Итак, главный совет должен быть: не постройте алгоритм, который будет пытаться использовать слишком много информации с аппарата. Либо вы можете использовать реальное значение epsilon, либо вы можете жестко закодировать что-то вроде 2e-15. Он будет работать на множестве разных машин.

+1

Это отличный ответ, но, к сожалению, принятый ответ прояснил все, о чем мне было интересно. –

+2

Нет проблем :) Я сохраню его, чтобы дать дополнительную информацию для дальнейших чтений ^^ –

+0

«использовать тот же формат для представления десятичных чисел»: на самом деле они двоичные, а не десятичные. –

Смежные вопросы