Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: разработка для Web > перл производит вычисления


Автор: Гость_Сергей 25.4.2005, 15:04
вот простенький скрипт
#!/usr/bin/perl
print "Content-type: text/html; charset=koi8-r\n\n";
for ($i=0.6; $i<=1.6; $i+=0.001) {
print "$i<br>\n";
}
ничего вроде сложного, должен столбец выводиться
0.6
0.601
0.602
...
1.6

но начиная гдето со значения 1.4 выдаёт
1.3999999999
1.4009999999
и т. д.

может это у меня только так?
и почему это так получается?

Автор: korob2001 25.4.2005, 15:15
Код

#!/usr/bin/perl
print "Content-type: text/html; charset=koi8-r\n\n";
for ($i=0.6; $i<=1.6; $i+=0.001) {
printf("%.3f<br>\n", $i);
}

Автор: Kiber_rat 25.4.2005, 15:20
Забавно, я немного переделал твой код и у меня получился правильный вывод, а твой действительно странно себя ведет... В любом случае можно в таких случаях использовать printf или sprinf
Вот мой код:
Код

#!/usr/bin/perl -w
print "Content-type: text/html; charset=koi8-r\n\n";
print $_/1000+0.001."<br>\n" for (600..1599);

Автор: Гость_Сергей 25.4.2005, 17:13
а почему же так получается?
может кто из знающих подскажет?

Автор: Kiber_rat 26.4.2005, 02:29
Вот порасспросил знакомого "гуру" smile Привожу цитату:
Цитата
Я-ж говорю - патамучта дроби. Подумай сам: дробей бесконечное кол-во, согласен?
А битов/байтов, которыми нужно задать любое число - конечное. Поэтому некоторые
(многие smile) дробные числа вообще не имеют представления на компе и округляются
в какую-нить сторону.
И чем больше ты с ними работаешь - тем больше погрешность накапливается.
Лечится это несколькими способами:
- работать только с целыми числами (т.е. умножить на коэффициент) а перед
  выводом разделить чтобы получить нужные числа
- работать с тектовыми представлениями чисел - очень медленно и неудобно, но
  100% точность
- использовать модули Math::* которые работают а-ля в тектовом виде, но
  написаны оптимизировано на C
Ну и т.д. Идея, я думаю, понятна. smile

Автор: korob2001 26.4.2005, 02:59
Причем это проблема не только в Perl, но и в других языках.

Автор: Ivan Kolesnikov 26.4.2005, 09:13
В десятичной системе
1.2 = 1*10^1 + 2*10^(-1)
Можно заметить:
0.2 = 1/5 или приблеженно равно = 1/8 + 1/16 + 1/128 = 25/128 = 0.1953125
Точного представления все равно не получится, потому что нет такого числа что (2^x) % 5 = 0
И получаем в двоичной системе
1*2^0+0*2^(-1)+0*2^(-2)+1*2^(-3)+1*2^(-4)+0*2^(-5)+0*2^(-6)+1*2^(-7)+... = 1.0011001...

Интересно, например в 3-ной системе 1/3 переходит в 0.1, причем точно smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)