В стандарте C99 различаются неявные и явные преобразования типов (6.3 Конверсии). Я думаю, но не мог найти, что неявные отведения выполняются, когда целевой тип имеет большую точность, чем источник, и может представлять его значение. [Это то, что я считаю, происходит от INT до DOUBLE]. Учитывая, что я смотрю на следующем примере:Понимание неявных преобразований для printf
#include <stdio.h> // printf
#include <limits.h> // for INT_MIN
#include <stdint.h> // for endianess
#define IS_BIG_ENDIAN (*(uint16_t *)"\0\xff" < 0x100)
int main()
{
printf("sizeof(int): %lu\n", sizeof(int));
printf("sizeof(float): %lu\n", sizeof(float));
printf("sizeof(double): %lu\n", sizeof(double));
printf(IS_BIG_ENDIAN == 1 ? "Big" : "Little"); printf(" Endian\n");
int a = INT_MIN;
printf("INT_MIN: %i\n", a);
printf("INT_MIN as double (or float?): %e\n", a);
}
Я был очень удивлен, обнаружив, что выход:
sizeof(int): 4
sizeof(float): 4
sizeof(double): 8
Little Endian
INT_MIN: -2147483648
INT_MIN as double (or float?): 6.916919e-323
Таким образом, значение с плавающей точкой Печатаемая субнормальным число с плавающей точкой вблизи минимальна субнормальны положительный двойной 4.9406564584124654 × 10^-324. Странные вещи происходят, когда я закомментировать две Printf для порядок байтов, я получаю другое значение для двойной:
#include <stdio.h> // printf
#include <limits.h> // for INT_MIN
#include <stdint.h> // for endianess
#define IS_BIG_ENDIAN (*(uint16_t *)"\0\xff" < 0x100)
int main()
{
printf("sizeof(int): %lu\n", sizeof(int));
printf("sizeof(float): %lu\n", sizeof(float));
printf("sizeof(double): %lu\n", sizeof(double));
// printf(IS_BIG_ENDIAN == 1 ? "Big" : "Little"); printf(" Endian\n");
int a = INT_MIN;
printf("INT_MIN: %i\n", a);
printf("INT_MIN as double (or float?): %e\n", a);
}
выход:
sizeof(int): 4
sizeof(float): 4
sizeof(double): 8
INT_MIN: -2147483648
INT_MIN as double (or float?): 4.940656e-324
- НКУ --version: (Ubuntu 4.8.2- 19ubuntu1) 4.8.2
- uname: x86_64 GNU/Linux
- опции компилятора, где: GCC -ox хс -Wall -Wextra -std = c99 --pedantic
- И да там, где одно предупреждение:
x.c: In function ‘main’:
x.c:15:3: warning: format ‘%e’ expects argument of type ‘double’, but argument 2
has type ‘int’ [-Wformat=]
printf("INT_MIN as double (or float?): %e\n", a);
^
Но я до сих пор не могу понять, что именно происходит.
- в небольшом порядке байт Я считаю MIN_INT как: 00 ... 0001 и MIN_DBL (Субнормальный) в 100..00 #, начиная с мантиссой, а затем экспонентом и заключить с
#
как знаковым битом. - Является ли эта форма применения спецификатора формата «% e» для int, является неявным литом ?, реинтерпрет?
Я потерян, пожалуйста, просветите меня.
Существует различие между 'cast'-ing и поставкой несовместимого' спецификатора формата '' для 'printf()'. Позднее действие приводит к UB. –
Я предлагаю вам изменить свой код, чтобы иметь один правильный printf и один неверный printf, затем скомпилировать его на сборку и посмотреть на разницу между ними. Вы узнаете, как двойной должен быть передан в функции varargs, и как он пытался передать ваш int как double. – JS1