Эта проблема может быть воспроизведена на g cc с 32-битной архитектурой Intel без оптимизации. Вот пример того, как это происходит: пример проводника компилятора .
Это связано с печально известной ошибкой 323 в g cc, которая изо всех сил пытается работать с Intel 80-битные регистры с плавающей запятой, которые шире, чем 64-битные регистры типа double
. Некоторые значения попадают в 80-битный регистр, а некоторые - в 64-битное значение памяти.
В вашем случае сначала вызывается approach(d)
, а затем переливается в память при вызове v.getLength()
. С другой стороны, значение approach(v.getLength())
не теряется и получает всю 80-битную точность регистра.
Когда вы сравниваете 80-битное точное значение и усеченное 64-битное значение, результат сравнения будет false
.
Возможное решение - избежать деления на 100 в approach()
, поскольку он вводит дополнительные биты. Вместо этого вы можете попробовать:
static constexpr double magnitude = 100.0;
const bool operator== (double d, const Point &v){
return floor(d * magnitude) == floor(v.getLength() * magnitude));
}