为什么从 float 到 int 的转换会返回 float 的整数部分(在 C 中)?

问题描述 投票:0回答:2

众所周知,将 float 转换为 int 后,int 变量获取 float 变量的整数部分,丢弃小数部分。

以32位浮点数为例,其值为-248.75,内存中的值如下:

float_t a = -248.75; // in binary: 11000011 01111000 11000000 00000000

如下图:

该二进制值代表以下十进制值:

11000011 01111000 11000000 00000000 = 3279470592

然后,据我所知,将该二进制内容转换为(无符号或无符号)整数,它应该返回以下值:

uint32_t u32 = (uint32_t) a;   -> 3,279,470,592  (**11000011 01111000 11000000 00000000**)
uint16_t u16 = (uint16_t) a;   -> 49152          (00000000 00000000 **11000000 00000000**)
uint8_t  u8  = (uint8_t)  a;   -> 0              (00000000 00000000 00000000 **00000000**)
int32_t  i32 = (int32_t)  a;   -> -1,131,986,944 (**01000011 01111000 11000000 00000000**) (the first bit is the sign)

那么,为什么这些变量的值却是248呢? (反之亦然,从整数到浮点)PD:我要的是技术背景

c casting floating-point binary
2个回答
0
投票

因为转换不是将浮点数的二进制表示形式复制为整数。 In 通过丢弃浮点数的小数部分将浮点数(无论如何表示)转换为整数

您想要查看所需数字的二进制表示形式:

  1. 使用
    union
uint32_t viaUnion(float x)
{
    union
    {
        uint32_t u32;
        float f;
    }un = {.f = x};

    return un.u32;
}
  1. 使用
    memcpy
    功能:
uint32_t viaMemcpy(float x)
{
    uint32_t u32;

    memcpy(&u32, &x, sizeof(u32));

    return u32;
}

0
投票

基本上:因为这就是 C 语言所说应该发生的事情。它与类型的底层二进制表示无关。

强制转换是显式转换,因此适用浮点到整数转换的规则。 C17 6.3.1.4:

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

如果您对纯二进制表示感兴趣,您可以使用指向字符的指针检查 C 中的任何类型:

float_t a = -248.75;
unsigned char* ptr = (unsigned char*)&a;
for(size_t i=0; i<sizeof(a); i++)
{
  printf("%.2X ", ptr[i]);
}

小端机上的输出:

00 C0 78 C3 
© www.soinside.com 2019 - 2024. All rights reserved.