Поскольку не каждое число может быть представлено значениями с плавающей запятой IEEE754.В какой-то момент вы получите число, которое не совсем представимо, и компьютер должен будет выбрать ближайший.
Если вы введете 0,05 в Harald Schmidt's excellent online converter
и сделаете ссылку на Запись в Википедии по IEEE754-1985 , в итоге вы получите следующие биты (мое объяснение этого следует):
s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm
0 01111010 10011001100110011001101
|||||||| |||||||||||||||||||||||
128 -+||||||| ||||||||||||||||||||||+- 1 / 8388608
64 --+|||||| |||||||||||||||||||||+-- 1 / 4194304
32 ---+||||| ||||||||||||||||||||+--- 1 / 2097152
16 ----+|||| |||||||||||||||||||+---- 1 / 1048576
8 -----+||| ||||||||||||||||||+----- 1 / 524288
4 ------+|| |||||||||||||||||+------ 1 / 262144
2 -------+| ||||||||||||||||+------- 1 / 131072
1 --------+ |||||||||||||||+-------- 1 / 65536
||||||||||||||+--------- 1 / 32768
|||||||||||||+---------- 1 / 16384
||||||||||||+----------- 1 / 8192
|||||||||||+------------ 1 / 4096
||||||||||+------------- 1 / 2048
|||||||||+-------------- 1 / 1024
||||||||+--------------- 1 / 512
|||||||+---------------- 1 / 256
||||||+----------------- 1 / 128
|||||+------------------ 1 / 64
||||+------------------- 1 / 32
|||+-------------------- 1 / 16
||+--------------------- 1 / 8
|+---------------------- 1 / 4
+----------------------- 1 / 2
Знак, будучи 0, является положительным.Показатель степени указывается однобитным отображением чисел слева: 64+32+16+8+2 = 122 - 127 bias = -5
, поэтому множитель равен 2 -5 или 1/32
.Смещение 127
позволяет отображать очень маленькие числа (например, близкие к нулю, а не отрицательные числа с большой величиной).
Мантисса немного сложнее.Для каждого бита вы накапливаете числа в правой части (после добавления неявного 1
).Следовательно, вы можете вычислить число как сумму {1, 1/2, 1/16, 1/32, 1/256, 1/512, 1/4096, 1/8192, 1/65536, 1/131072, 1/1048576, 1/2097152, 1/8388608}
.
Когда вы сложите все это, вы получите 1.60000002384185791015625
.
Когда вы умножите на намножитель 1/32
(рассчитанный ранее из битов экспоненты), вы получите 0.0500000001
, так что вы можете видеть, что 0.05
это уже не представлен точно.Этот битовый шаблон для мантиссы фактически такой же, как 0.1
, но при этом показатель степени равен -4, а не -5, и поэтому 0.1 + 0.1 + 0.1
редко равен 0.3
(это, кажется, любимое интервьювопрос).
Когда вы начнете добавлять их, эта небольшая ошибка будет накапливаться, поскольку вы не только увидите ошибку в самом 0.05
, но и ошибки могут появляться на каждом этапе накопления - невсе числа 0.1
, 0.15
, 0.2
и т. д. могут быть представлены точно так же.
В конце концов, ошибки станут достаточно большими, и они начнут появляться в числе, если выиспользуйте точность по умолчанию.Вы можете отложить это на некоторое время, выбрав собственную точность, например:
#include <iostream>
#include <iomanip>
:
std::cout << std::setprecison (2) << time << '\n';
Это не изменит значение переменной , , но даст вам больше пространства для дыханиядо того, как ошибки станут видны.
Кроме того, некоторые люди рекомендуют избегать std::endl
, так как это вызывает сброс буферов.Если ваша реализация работает сама по себе, это произойдет с терминальными устройствами, когда вы все равно отправите новую строку.И если вы перенаправили стандартный вывод на нетерминал, вы, вероятно, не хотите очищать каждую строку.На самом деле не имеет отношения к вашему вопросу, и, вероятно, это не будет иметь большого значения в подавляющем большинстве случаев, просто вопрос, о котором я подумала.