如何修正C语言中用位运算翻转float符号的错误?
问题分析与修复方案
问题根源:你完全搞错了操作对象的含义。函数参数
uint32_t f是float类型的二进制位表示(不是整数的二进制),而你现在的代码在计算这个整数的2's补码,这是把float的二进制当成整数来处理,结果自然完全不符合预期。32位float的格式是:最高位(第31位)是符号位,0表示正数,1表示负数。要翻转符号,只需要单独翻转这一位就行,不需要对整个数做补码运算。
修复后的代码:
uint32_t sign_flip(uint32_t f) { // 0x80000000 是只保留最高位(符号位)的掩码 return f ^ 0x80000000; }为什么原来的代码会得到奇怪的结果:
以输入-42为例,它的float二进制表示对应的uint32_t值是0xC2280000。你的代码对这个整数做2's补码运算,得到的结果是0x3DD80000,把这个值解析成float就是0.10546875,这就是你看到的错误输出。验证修复效果:
当输入是-42对应的float二进制位0xC2280000,异或0x80000000后得到0x42280000,这个值解析成float就是42,完全符合预期输出。
内容的提问来源于stack exchange,提问作者FreeAntiVirus
相关产品推荐
相关产品推荐

