当double值超出char范围时,C中的double to char转换规则

时间:2018-06-02 02:06:46

标签: c

我已经问了一个密切相关的question,这是一个相同的扩展案例。

请考虑以下代码:

#include<stdio.h>
int main(void)
{
 char c1 = 3000.5;
 printf("%d\n",c1);
}

上述代码的输出是

127

请解释右边的double值如何转换为char。 我对这个过程的理解如下:

浮点表示中的double值3000.5如下:

01000000 10100111 01110001 0000000000000000 00000000 00000000 00000000

如果我们只考虑最后8位,那么得到的二进制数是

00000000

在2的补码表示中是十进制0.这与结果不一致。

如果我们忽略小数部分,那么我们得到3000,当转换为char时,结果是-72,这又与结果不一致。

如果我对这个概念有错误的理解,请纠正我。

3 个答案:

答案 0 :(得分:3)

发生的事情是real floating-integer conversion,会发生什么

  

丢弃小数部分(截断为零)。

     
      
  • 如果结果值可以由目标类型表示,则使用该值
  •   
  • 否则,行为未定义
  •   

由于截断值3000很大,以适应char undefined behavior

答案 1 :(得分:3)

  

当double值超出char

范围时,C中的double to char转换规则

未定义的行为,如果double值,一旦失去其分数,就会超出char范围。

将3000.5转换为导致-72或127的char未定义行为的示例。下次运行代码时,结果可能是42或系统崩溃 - 它是UB。

double这样的浮点转换包含两个步骤

  

当实数浮动类型的有限值被转换为除_Bool以外的整数类型时,小数部分被丢弃(即,该值被截断为零)。如果整数部分的值不能用整数类型表示,则行为是未定义的。 C11§6.3.1.41

FP和整数的格式与指定的转换无关。

转换为带有-128到127范围的签名char时,{-1}}的值为-128.999 ...到+127.999 ...已明确定义。不在该范围内的值会导致UB。

答案 2 :(得分:3)

除了@chux提到的,声明

char c1 = 3000.5;

未定义的行为,因为c1signed字符&amp;签名字符的最大限制为127,即范围-128 to + 127

在您的特定情况下,将任何大于SCHAR_MAX的值分配给c1会被截断为SCHAR_MAX(127)本身。这意味着char c1 = 127.5;char c1 = 3000.5;会产生相同的输出,因此输出为127

此外,当您使用-Wall标志编译程序时,它可能会警告您喜欢

  

隐式常量转换溢出[-Werror = overflow]

所以答案就是警告本身。建议您认真注意编译器警告&amp;将所有警告视为错误。

gcc -Wall -Wstrict-prototypes -Werror test.c
相关问题