Как уже упоминал Марк Рэнсом в комментариях, вывод, который вы видите, является просто краткой формой для фактического значения, которое хранится в вашем float или double значении.Вы можете увидеть больше цифр, используя, например, std::setprecision(15)
.
Стандартные значения с плавающей запятой одинарной точности имеют 32 бита, 23 из которых зарезервированы для мантиссы.Предполагается, что наиболее значимый бит мантиссы равен единице (но не сохраняется), когда значение с плавающей запятой не равно нулю.Это означает, что у вас есть 24 бита для хранения, и максимальное значение, которое может хранить мантисса, составляет 2 ^ 24 или 16777216. Как вы можете видеть, вы можете хранить около 7 цифр без потери точности.Я говорю «примерно», потому что не все десятичные представления значения с плавающей запятой могут быть выражены с одинаковой точностью в двоичном формате.
Вот интересный эксперимент:
long n0 = 16777210;
for (int i = 0; i < 10; i++)
{
long n = n0 + i;
std::cout << "n=" << n << " / ((float)n)=" << std::setprecision(15) << ((float)n) << std::endl;
}
Вывод:
n=16777210 / ((float)n)=16777210
n=16777211 / ((float)n)=16777211
n=16777212 / ((float)n)=16777212
n=16777213 / ((float)n)=16777213
n=16777214 / ((float)n)=16777214
n=16777215 / ((float)n)=16777215
n=16777216 / ((float)n)=16777216
n=16777217 / ((float)n)=16777216
n=16777218 / ((float)n)=16777218
n=16777219 / ((float)n)=16777220
Число 3012916000 слишком велико, чтобы его можно было хранить точно в значении с плавающей запятой одинарной точности.Когда вы выводите свой номер следующим образом:
std::cout << "x float = " << std::setprecision(15) << xFloat << std::endl;
Тогда получается:
x float = 3012915968
Двойные значения имеют 52 + 1-битную мантиссу, и поэтому ваш номер может быть сохранен точно:
std::cout << "xDouble = " << std::setprecision(15) << xDouble << std::endl;
Выход:
xDouble = 3012916000