почему% f после этого равно 0,000000.
Согласно стандарту C, поскольку %d
ожидает int
, а вы передали double
, происходит неопределенное поведение и все позволено.
В любом случае: я использовал http://www.binaryconvert.com/convert_double.html для преобразования двойных чисел в биты:
120.1 === 0x405E066666666666
125.12 === 0x405F47AE147AE148
Я полагаю, что ваша платформа x86-i sh, прямым порядком, с моделью данных ILP32.
Спецификатор формата %d
printf предназначен для int
, а sizeof(int)
- 4 байта или 32 бита в LP64. Поскольку архитектура имеет прямой порядок байтов и стек тоже, первые 4 байта из стека равны 0x66666666
, и распечатывается ее десятичное значение, равное 1717986918
.
. В стеке остаются три 32 -битные слова с прямым порядком байтов, давайте разделим их 0x405E0666 0x147AE148 0x405F47AE
.
Спецификатор формата %f
printf
предназначен для double
и sizeof(double)
на вашей платформе 8 или 64 бита. Мы уже прочитали 4 байта из стека, и теперь мы читаем 8 байтов. Вспоминая о порядке байтов, мы читаем 0x147AE148405E0666
, который преобразуется в двойной. Я снова использовал этот сайт и преобразовал гекс в двойной, в результате чего 5.11013578783948654276686949883E-210
. E-210
- это очень и очень небольшое число. Поскольку %f
по умолчанию печатает с точностью до 6 цифр, начальные 7 цифр числа равны 0, поэтому печатаются только нули. Если вы используете спецификатор формата %g
printf, то номер будет напечатан как 5.11014e-210
.