Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

PERL: неправильные вычисления с плавающей точкой

46K
18 февраля 2009 года
XoRe
3 / / 18.02.2009
Скрипт:
------------------------------
#!/usr/bin/perl

$a = 601; foreach $b (0..9) { $c = $a + $b / 10; print "$c: " . (($c * 100) - ($c * 10 * 10)) . "\n"; }
------------------------------

Выдает:
601: 0
601.1: 0
601.2: 7.27595761418343e-12
601.3: -7.27595761418343e-12
601.4: 0
601.5: 0
601.6: 0
601.7: 7.27595761418343e-12
601.8: -7.27595761418343e-12
601.9: 0

Вопрос:
Почему???

Проверялось на разных машинах с конфигурациями:
Perl 5.8.8/FreeBSD 7.0;
Perl 5.8.8/Linux gentoo (kernel 2.6.20-gentoo-r8);
Perl 5.8.8/Linux gentoo (kernel 2.4.32-gentoo-r7);
Perl 5.10.0/Linux Ubuntu 8.10 (kernel2.6.27-12-generic);
5
18 февраля 2009 года
hardcase
4.5K / / 09.08.2005
Цитата: XoRe
Скрипт:
------------------------------
#!/usr/bin/perl

$a = 601; foreach $b (0..9) { $c = $a + [COLOR=Red]$b / 10[/COLOR]; print "$c: " . (($c * 100) - ($c * 10 * 10)) . "\n"; }
------------------------------

Это целочисленная операция так как $b - целое число, результатом его будет честный целочисленный ноль.
Дальнейшие вычисления дают если не 0, то предельно близкое к нему число.

Попробуйте заменить на $b / 10.0, увидите, что все встанет на свои места.

46K
18 февраля 2009 года
XoRe
3 / / 18.02.2009
Цитата: hardcase
Это целочисленная операция так как $b - целое число, результатом его будет честный целочисленный ноль.
Дальнейшие вычисления дают если не 0, то предельно близкое к нему число.

Попробуйте заменить на $b / 10.0, увидите, что все встанет на свои места.



Попробовал:

$a = 601; foreach $b (0..9) { $c = $a + $b / 10.0; print "$c: " . (($c * 100) - ($c * 10 * 10)) . "\n"; }

601: 0
601.1: 0
601.2: 7.27595761418343e-12
601.3: -7.27595761418343e-12
601.4: 0
601.5: 0
601.6: 0
601.7: 7.27595761418343e-12
601.8: -7.27595761418343e-12
601.9: 0

Не помогло.

Насколько я знаю, perl не использует int для хранения чисел.
Для чисел используется signed long double.

Буду рад мыслям на эту тему.
Просьба внимательно прочиать вопрос и/или попробовать сию конструкцию у себя.
Вопрос весьма нетривиальный.

5
18 февраля 2009 года
hardcase
4.5K / / 09.08.2005
Сейчас посмотрел внимательнее на код.
Цитата: XoRe
Вопрос весьма нетривиальный.

Вас смущают числа типа 7.27595761418343e-12 ?
Это близкие к нулю значения.
Они будут в любом языке программирования, работающим с числами двойной точности.

В данном случае это может происходить из за того, что умножение сразу на 100 отличается от двух умножений на 10. Это связано с представлением вещественных чисел в памяти машины - определенная потеря точности неизбежна.

46K
19 февраля 2009 года
XoRe
3 / / 18.02.2009
Сказываются пробелы в образовании.
Спасибо за информацию)

http://rt.perl.org/rt3/Public/Bug/Display.html?id=63304
Проблему можно считать решенной )
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог