简体   繁体   English

如何在 C 中使用按位运算符翻转浮点数的符号

[英]How to flip the sign of a float using bitwise operators in C

This is the code I have so far这是我到目前为止的代码

// given the 32 bits of a float return it with its sign flipped
uint32_t sign_flip(uint32_t f) {
    int mask = 1;    
    f = ~f; // 1's Complement 
    while (mask > 0 && (mask & f)) 
    { 
        f ^= mask; 
        mask <<= 1; 
    } 
    f ^= mask; // 2's complment 
    return f; // REPLACE ME WITH YOUR CODE
}

Expected output:预期 output:

./sign_flip -42
sign_flip(-42) returned 42

output: output:

./sign_flip -42
sign_flip(-42) returned 0.10546875

How would I go about fixing this?我将如何解决这个问题? I am not sure what the issue is我不确定问题是什么

IEEE 754 floating-point format is not 2's complement. IEEE 754 浮点格式不是 2 的补码。 Just flip most-significant bit:只需翻转最重要的位:

float f = 42;
*(uint32_t*)&f ^= (1 << 31);
printf("%f\n", f);

It is reasonable to expect a float to have a single isolated sign bit regardless of encoding, IEEE 754 or not.无论编码如何,IEEE 754 与否,都可以合理地期望float具有单个隔离符号位。

Find that bit and flip it.找到那个位并翻转它。 No need to assume common endian-ness of float/uint32_t .无需假设float/uint32_t的通用字节序。 Use a union to avoid strict aliasing violations.使用union来避免严格的别名违规。

uint32_t sign_flip(uint32_t f) {
  assert(sizeof(float) == sizeof(uint32_t));
  static const union {
    uint32_t u32;
    float f;
  } plus1 = { .f = 1.0f }, minus1 = { .f = -1.0f };
  return f ^ (plus1.u32 ^ minus1.u32);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM