C99 标准区分隐式和显式类型转换(6.3 转换)。我猜想,但找不到,当目标类型比源更精确并且可以表示它的值时,会执行隐式转换。 [这就是我认为从 INT 到 DOUBLE 发生的事情]。鉴于此,我看下面的例子:
#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
因此打印的浮点值是一个次正规 float ,接近最小次正规正 double 值 4.9406564584124654 × 10^−324。当我为字节顺序注释掉两个 printf 时,奇怪的事情发生了,我得到了 double 的另一个值:
#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
- gcc --version: (Ubuntu 4.8.2-19ubuntu1) 4.8.2
- uname: x86_64 GNU/Linux
- 编译器选项,其中:gcc -o x x.c -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#,从尾数开始,然后是指数,最后以
#
作为结尾符号位。 - 这种在 int 上应用“%e”格式说明符的形式是隐式转换吗?是重新解释转换吗?
我迷路了,请赐教。
最佳答案
printf("INT_MIN as double (or float?): %e\n", a);
上一行有问题您不能使用%e
来打印整数。行为未定义。
你应该使用
printf("INT_MIN as double (or float?): %e\n", (double)a);
或
double t = a;
printf("INT_MIN as double (or float?): %e\n", t);
Related post : 这篇文章解释了在 printf 中使用不正确的打印说明符如何导致 UB。
关于c - 了解 printf 的隐式转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26751361/