Спасибо всем за ваши ответы. Хотя почти все вы помогли мне взглянуть в правильном направлении, я не мог понять точную причину такого поведения. Поэтому я провел небольшое исследование в дополнение к чтению страниц, на которые вы, ребята, указали мне. Вот мое понимание этого поведения:
Числа с плавающей запятой одинарной точности обычно используют 4 байта для хранения на архитектурах x86 / x86-64. Однако не все 32 бита (4 байта = 32 бита) используются для хранения величины числа.
Для хранения в виде плавающего типа с одинарной точностью входной поток форматируется в следующей записи (несколько похожей на научную запись):
(-1)^s x 1.m x 2^(e-127), where
s = sign of the number, range:{0,1} - takes up 1 bit
m = mantissa (fractional portion) of the number - takes up 23 bits
e = exponent of the number offset by 127, range:{0,..,255} - takes up 8 bits
и затем сохраняется в памяти как
0th byte 1st byte 2nd byte 3rd byte
mmmmmmmm mmmmmmmm emmmmmmm seeeeeee
Поэтому десятичное число 125.1 сначала преобразуется в двоичную форму, но ограничено 24 битами, так что мантисса представлена не более чем 23 битами. После преобразования в двоичную форму:
125.1 = 1111101.00011001100110011
ПРИМЕЧАНИЕ: 0,1 в десятичном виде можно представить с точностью до бесконечных битов в двоичном формате, но компьютер ограничивает представление 17 битами, поэтому полное представление не превышает 24 бит.
Теперь, преобразовав его в указанную запись, мы получим:
125.1 = 1.111101 00011001100110011 x 2^6
= (-1)^0 + 1.111101 00011001100110011 x 2^(133-127)
что подразумевает
s = 0
m = 11110100011001100110011
e = 133 = 10000101
Следовательно, 125.1 будет сохранено в памяти как:
0th byte 1st byte 2nd byte 3rd byte
mmmmmmmm mmmmmmmm emmmmmmm seeeeeee
00110011 00110011 11111010 01000010
После передачи в функцию printf () поток вывода генерируется путем преобразования двоичной формы в десятичную. Байты фактически сохраняются в обратном порядке (из входного потока) и, следовательно, читаются в следующем порядке:
3rd byte 2nd byte 1st byte 0th byte
seeeeeee emmmmmmm mmmmmmmm mmmmmmmm
01000010 11111010 00110011 00110011
Далее он преобразуется в специальную запись для преобразования
(-1)^0 + 1.111101 00011001100110011 x 2^(133-127)
Об упрощении вышеприведенного представления:
= 1.111101 00011001100110011 x 2^6
= 1111101.00011001100110011
И, наконец, преобразование его в десятичное число:
= 125.0999984741210938
но с плавающей запятой одинарной точности может представлять только до 6 десятичных знаков, поэтому ответ округляется до 125.099998 .