В настоящее время я пытаюсь подробно узнать о представлении с плавающей запятой, поэтому я немного поиграл. Делая это, я наткнулся на какое-то странное поведение; Я не могу понять, что происходит, и я был бы очень благодарен за понимание. Извиняюсь, если на это был дан ответ, мне было довольно сложно Google!Странное поведение при сравнении литого поплавка с нолем
#include <iostream>
#include <cmath>
using namespace std;
int main(){
float minVal = pow(2,-149); // set to smallest float possible
float nextCheck = static_cast<float>(minVal/2.0f); // divide by two
bool isZero = (static_cast<float>(minVal/2.0f) == 0.0f); // this evaluates to false
bool isZero2 = (nextCheck == 0.0f); // this evaluates to true
cout << nextCheck << " " << isZero << " " << isZero2 << endl;
// this outputs 0 0 1
return 0;
}
По сути то, что происходит это:
- Я поставил MINVAL быть наименьшим поплавок, который может быть представлен с использованием одинарной точности
- разделив на 2 должны давать 0 - мы на минимум
- Действительно, isZero2 действительно возвращает true, но isZero возвращает false.
Что происходит - я бы подумал, что они идентичны? Компилятор пытается быть умным, говоря, что деление любого числа не может привести к нулю?
Благодарим за помощь!
Как вы уверены, что 'pow (2, -149)' возвращает наименьший возможный поплавок? Существует множество проблем с расчетом расчета. – deepmax
Кажется, что работает. Бинарное представление возвращает 1, что действительно является наименьшим возможным поплавком: Знак = 0; Exponent = 0; Mantissa = 1, так: 2^(- 23) * 2^(- 126) = 2^(- 149) – noctilux
Получаю ваш ожидаемый результат на g ++ 4.8.2. '0 1 1'. –