в основном с помощью float вы получаете 32 бита, которые кодируют
VALUE = SIGN * MANTISSA * 2 ^ (128 - EXPONENT)
32-bits = 1-bit 23-bits 8-bits
и сохраняется как
MSB LSB
[SIGN][EXPONENT][MANTISSA]
, поскольку вы получаете только 23 бита, это количество «точности», которое вы можете хранить. Если вы пытаетесь представить дробь, которая является иррациональной (или повторяющейся) в основании 2, последовательность битов будет округлена до 23-го бита.
0,7 основание 10 равно 7/10, что в двоичном виде 0b111 / 0b1010, вы получите:
0.1011001100110011001100110011001100110011001100110011... etc
Поскольку это повторяется, с фиксированной точностью невозможно точно представить это.
то же самое касается 0,8, который в двоичном виде:
0.1100110011001100110011001100110011001100110011001101... etc
Чтобы увидеть, каково значение этих чисел с фиксированной точностью, вам нужно «обрезать их» по количеству битов, которые вы выполняете, и выполнить математику. Единственная хитрость в том, что первая цифра подразумевается и не сохраняется, так что технически вы получаете дополнительный бит точности. Из-за округления последний бит будет равен 1 или 0 в зависимости от значения усеченного бита.
Таким образом, значение 0,7 фактически равно 11 744 051/2 ^ 24 (без эффекта округления) = 0,699999988, а значение 0,8 составляет 13 421 773/2 ^ 24 (с округлением в большую сторону) = 0,800000012.
Это все, что нужно сделать:)