C中的两个补充和信息丢失

时间:2014-09-02 08:35:35

标签: c casting twos-complement

我想做浮动数据的两个补充。

    unsigned long Temperature ; 
    Temperature = (~(unsigned long)(564.48))+1;

但问题是演员失去了信息,564而不是564.48。 我可以在不丢失信息的情况下完成这两个补充吗?

3 个答案:

答案 0 :(得分:1)

这是一件非常奇怪的事情;浮点数存储为2s补码,因此它没有多大意义。

无论如何,您可以使用旧的union技巧:

union {
  float real;
  unsigned long integer;
} tmp = { 564.48 };

tmp.integer = ~tmp.integer + 1;
printf("I got %f\n", tmp.real);

当我尝试它(在ideone上)时,它打印出来:

I got -0.007412

请注意,这取决于未指定的行为,因此如果您的编译器没有以最直接的方式实现访问,它可能会中断。这是 undefined 行为的不同形式(这会使代码无效),但仍然不是最佳的。有人告诉我,新的标准使它更清晰,但我还没有找到确切的参考,所以...考虑自己警告。

答案 1 :(得分:1)

你不能在浮点数上使用~(它必须是整数类型):

#include <stdio.h>

void print_binary(size_t const size, void const * const ptr)
{
    unsigned char *b = (unsigned char *) ptr;
    unsigned char byte;
    int i, j;

    for (i = size - 1; i >= 0; i--) {
        for (j = 7; j >= 0; j--) {
            byte = b[i] & (1 << j);
            byte >>= j;
            printf("%u", byte);
        }
    }
    printf("\n");
}

int main(void)
{
    float f = 564.48f;
    char *p = (char *)&f;
    size_t i;

    print_binary(sizeof(f), &f);
    for (i = 0; i < sizeof(float); i++) {
        p[i] = ~p[i];
    }
    print_binary(sizeof(f), &f);
    f += 1.f;
    return 0;
}

输出:

01000100000011010001111010111000
10111011111100101110000101000111

当然print_binary用于测试结果,删除它,并且(正如@barakmanos指出的那样)print_binary假设小端,其余代码不受endiannes的影响:< / p>

#include <stdio.h>

int main(void)
{
    float f = 564.48f;
    char *p = (char *)&f;
    size_t i;

    for (i = 0; i < sizeof(float); i++) {
        p[i] = ~p[i];
    }
    f += 1.f;
    return 0;
}

答案 2 :(得分:0)

将浮点值转换为整数值会更改&#34;位内容&#34;那个价值。

为了在&#34;位内容&#34;上执行两个补码一个浮点值:

float f = 564.48f;
unsigned long Temperature = ~*(unsigned long*)&f+1;

确保sizeof(long) == sizeof(float),或使用double代替float