当双精度值超出字符范围时,C中的双精度到字符转换规则
我已经问了一个密切相关的问题,这是一个同样的扩展案例 考虑以下代码:当双精度值超出字符范围时,C中的双精度到字符转换规则,c,C,我已经问了一个密切相关的问题,这是一个同样的扩展案例 考虑以下代码: #include<stdio.h> int main(void) { char c1 = 3000.5; printf("%d\n",c1); } 请解释如何将右侧的双精度值转换为字符。 我对该过程的理解如下: 01000000 10100111 01110001 0000000000000000 00000000 00000000 00000000 浮点表示法中的双精度值3000.5如下所示: 01000
#include<stdio.h>
int main(void)
{
char c1 = 3000.5;
printf("%d\n",c1);
}
请解释如何将右侧的双精度值转换为字符。
我对该过程的理解如下:
01000000 10100111 01110001 0000000000000000 00000000 00000000 00000000
浮点表示法中的双精度值3000.5如下所示:
01000000 10100111 01110001 0000000000000000 00000000 00000000 00000000
如果只考虑最后8位,则得到的二进制数是
00000000
在2的补码表示法中,它是十进制0。这与结果不一致
如果我们忽略分数部分,那么我们得到3000,当转换成char时,结果是-72,这与结果不一致
如果我对这个概念有错误的理解,请纠正我。发生的事情是a,发生的事情是
小数部分将被丢弃(向零截断)
- 如果结果值可以由目标类型表示,则使用该值
- 否则,行为是未定义的
3000
太大,无法放入char
中
当双精度值超出字符范围时,C中的双精度到字符转换规则
这是未定义的行为,如果double
值丢失其分数,则超出char
范围
将3000.5转换为char
导致-72或127是未定义行为的示例。下次代码运行时,结果可能是系统崩溃,这是UB
浮点(如
double
的转换由两个步骤组成
当实浮点类型的有限值转换为除\u Bool
以外的整数类型时,小数部分被丢弃(即,该值被截断为零)。如果整数部分的值不能用整数类型表示,则行为未定义。C11§6.3.1.4 1
FP和整数的格式与指定的转换无关
在转换为带符号的
char
in(范围为-128到127)时,值为-128.999的double
。。。至+127.999。。。定义明确。不在该范围内的值将导致UB。除了@chux提到的以外,该声明
char c1 = 3000.5;
当c1
为signed
字符时,具有未定义的行为,且有符号字符的最大限制为127
,即范围-128到+127
在您的特定情况下,将任何大于SCHAR_MAX的值赋给c1
会被截断为SCHAR_MAX(127)
本身。这意味着charc1=127.5代码>和字符c1=3000.5
产生相同的输出,因此输出为127
另外,当您使用-Wall
标志编译程序时,它可能会向您发出警告
隐式常量转换中溢出[-Werror=溢出]
所以答案就在警告本身。建议您认真注意编译器警告&将所有警告视为错误
gcc -Wall -Wstrict-prototypes -Werror test.c
@Someprogrammerdude:请解释一下这个转换是如何进行的,以及我们是如何得到127的结果的。@Someprogrammerdude:Char在我的系统中签名的,我正在Ubuntu 14.04操作系统上使用gcc编译器。什么可能的实施会产生这样的结果?请解释一下,除了这是一个未定义的事实之外;浮点表示法是完全不相关的。C中的转换是根据值定义的,而不是表示形式。浮点数与补码无关。在这里,您可以看到double是如何转换为二进制的