理解C语言中的位级浮点乘法?

理解C语言中的位级浮点乘法?,c,floating-point,bit-manipulation,bit,C,Floating Point,Bit Manipulation,Bit,我尝试在C中实现两次float\u(float\u位x),它在位级别上将x乘以2。 我将float_的结果与用C实现的实际浮点乘法进行了两次比较,但发现了一个差异 float\u两次(0X800001)产生0X1000001,我认为这是正确的。据我所知,0X80001是指数1和小数部分1的浮点表示。因为它是一个标准化的值,我相信在指数部分加上一个就足够了 但是,((浮点)0X800001)*2.0产生0X1000002 这似乎是无符号整数的乘法,而不是浮点值 总而言之,这些是我的问题 两次浮动(

我尝试在C中实现两次
float\u(float\u位x)
,它在位级别上将
x
乘以2。 我将float_的结果与用C实现的实际浮点乘法进行了两次比较,但发现了一个差异

float\u两次(0X800001)
产生
0X1000001
,我认为这是正确的。据我所知,
0X80001
是指数
1
和小数部分
1
的浮点表示。因为它是一个标准化的值,我相信在指数部分加上一个就足够了

但是,
((浮点)0X800001)*2.0产生
0X1000002

这似乎是无符号整数的乘法,而不是浮点值

总而言之,这些是我的问题

  • 两次浮动(0X800001)
  • 的正确输出是什么

  • 如果正确的输出是
    0X1000001
    ,为什么C计算
    ((浮点)0X800001)*2.0
    0X1000002


  • 您的测试不正确:
    ((float)0X800001)
    将整数值
    0X800001
    转换为最接近的
    float
    值,而不是具有相同位表示的
    float

    要检查结果,必须执行类型双关,这可以通过
    memcpy
    便携式完成:

    #include <stdint.h>
    #include <string.h>
    
    typedef uint32_t float_bits;
    
    float_bits check_twice(float_bits x) {
        float f;
        float_bits r;
        memcpy(&f, &x, sizeof f);
        f *= 2;
        memcpy(&r, &f, sizeof r);
        return r;
    }
    
    #包括
    #包括
    typedef uint32 t浮点位;
    浮动位检查两次(浮动位x){
    浮动f;
    浮点数r;
    memcpy(&f,&x,sizeof);
    f*=2;
    memcpy(r&f、sizeof r);
    返回r;
    }
    
    (float)0X800001
    表示将整数
    0X800001
    转换为具有最接近数值的浮点数,它不会将位模式解释为浮点数
    (float)1==1.0
    您可能需要查看,它将浮点数减半而不是加倍。但是请注意:(i)代码非常不可移植;(ii)不包括任何特殊情况,如NANs;(iii)它处理非规范化的数字,但不处理溢出(当然,当你将数字减半时,不会发生溢出)。非常感谢。现在我理解了代码中的问题。我应该使用像reinterpret_cast这样的东西,对吗?@Kang在C中没有reinterpret_cast这样的东西。啊哈!你发现了我一直在传播的
    memcpy
    东西。@JL2210:我很抱歉承认这一点
    f=*(float*)&x更为明确。。。但由于严格的别名规则,无法使用。@chqrlie:未定义,无法使用。没有“严格的别名规则”表明您不能这样做。这只是一个从未定义过的行为。R:这只是一个从未定义过的行为,这是一个相当大胆的说法!严格的别名规则使其自1990年Ansi C以来未定义,以允许更好的优化,这有时似乎违反直觉。太糟糕了,Dennis R.不能告诉我们他是否打算让
    f=*(float*)&x在C语言的早期表现出预期的行为。。。他70年代的C参考手册,在cast语法发明之前,展示了更糟糕的类型双关方法:pp23,24