Тяжела и неказиста жизнь простого программиста...

Oct 27, 2007 23:33

Приятель показал замечательный баг, который он только что искоренил в коде. Все мы знаем, что floating-point переменные сравнивать на равенство очень опасно, но ведь всё равно иногда сравниваем, да? Так вот, имелся такой код:

double x = ;
double y = x;
Read more... )

Leave a comment

Comments 18

spamsink October 28 2007, 07:48:30 UTC
Ай, хорошо! В GCC на этот счет есть опция -ffloat-store, а как в других компиляторах - не знаю.

Reply

kot_ivanovich October 28 2007, 07:53:49 UTC
Это и был gcc. Но в большой вычислительной системе, где скорость - наше всё, -ffloat-store напишет только сумасшедший. Уж лучше мы их будем сравнивать поаккуратнее...

Reply

spamsink October 28 2007, 18:23:08 UTC
-ffloat-store хорош для быстрого выяснения, где кроется ошибка. А ликвидировать ее можно и более аккуратным сравнением, и с помощью использования long double в ключевых местах, и с помощью FLDCW(FSTCW() & ~0x100) в начале программы.

Reply


mbla October 28 2007, 08:48:34 UTC
Ни фига себе! Интересно, сколько времени он искал?

Reply

kot_ivanovich October 28 2007, 15:59:02 UTC
Приятель - могуч невероятно, думаю, что искал недолго. К тому же баг изолировали другие, к нему пришли только, когда встали в тупик.

Самое печальное, что нет хорошего универсального решения. Дейкстра где-то писал, что они однажды решили сделать в каком-то компиляторе операцию равенства между вещественными числами так, чтобы она пренебрегала парой последних битов. Оказалось еще хуже: они потеряли свойство (A = B) & (B = C) ⇒ (A = C) и последствия были тяжелы...

Reply


ex_juan_gan October 29 2007, 00:31:45 UTC
Шутки шутками, а это грязный баг. Ведь не обязательно складывать это дело в память, можно просто в регистре же округлить до стандартного плавающего. И если режим округления в процессе не менять... ;)

Reply

kot_ivanovich October 29 2007, 01:35:13 UTC
Не знаю, наверное, лучше было бы округлять. Я только боюсь, что решений без trade-offs не бывает: спасаем логичность, теряем скорость и/или точность. На самом деле программист просто не должен писать (y == x) никогда, такая запись всегда неаккуратное выражение какого-то другого смысла, например (fabs(y - x) < epsilon) или (fabs(y - x) < epsilon*fabs(x)) или еще чего. А в обсуждаемом примере было вообще лучше булевский флажок завести.

Reply


Хм, по-идее, вот такое и следовало бы в code_wtf poige November 16 2007, 02:19:42 UTC
:)

Reply

kot_ivanovich November 16 2007, 07:23:47 UTC
А это не WTF... Программист, который написал такое, глубоко неправ, но на WTF оно не тянет. Никто, из тех кого я знаю, не сказал с ходу: Ну это же очевидный баг!

Reply

> Ну это же очевидный баг! poige November 16 2007, 07:29:28 UTC
В том-то и дело!

> // Сюда программа не попадает никогда, даже когда игрека никто не менял!!!

- вот тут так и хочется добавить «-- WTF?!» Так что WTF оно WTF и есть. :)

Reply


sloppik February 1 2010, 12:08:11 UTC
Какая прелесть - обязательно своим студентам раскажу! Спасибо!

Reply


Leave a comment

Up