获取双精度词中最重要的单词

时间:2013-05-23 11:28:54

标签: c

我想获取double变量的最重要的32位字。

我知道double长度为8个字节,我希望我的函数返回unsigned long,它将保存double的4个最重要的字节。

unsigned long doublesmsw(double value);

int main()
{
  double d=54645654663905 ;
  unsigned long fin=doublesmsw(d);
  printf("%lu", fin );
  return 0;
}

unsigned long doublesmsw(double value)
{
  unsigned long long mask=0x00000000ffffffff ;
  return ((unsigned long long) value>>32 & mask);
}

3 个答案:

答案 0 :(得分:4)

value类型转换为unsigned long long只需将其截断为整数,会在double中生成unsigned long long的内存表示形式。请改用memcpy

unsigned long doublesmsw(double value)
{
    unsigned long r;
    memcpy(&r, &value, sizeof(r));
    // or memcpy(&r, (char *)&value + 4, sizeof(r));, depending on endianness
    return r;
}

或者,正如建议的那样,如果目标体系结构对整数和浮点数使用相同的字节顺序(它几乎总是这样):

unsigned long doublesmsw(double value)
{
    unsigned long long r;
    memcpy(&r, &value, sizeof(r));
    return r >> 32;
}

答案 1 :(得分:2)

您需要引用相同的内存区域,而不仅仅是转换值。在C99(或其附近)允许别名优化之后执行此操作的一种方法是强制转换联合,例如

union doubleUll {
    double d;
    unsigned long long ull;
};

unsigned long doublesmsw(double value)
{
    union doubleUll u;
    u.d = value;
    return (u.ull >> 32) & mask;
}

...但是Kerrek是正确的,这实际上是C99未定义的,但它是相当普遍的,并且是在编译器开始采用它之后,在21世纪初避免严格别名问题的推荐方法之一。请在此处查看较长时间的内容:Understanding Strict Aliasing

答案 2 :(得分:0)

像这样:

uint32_t msw(double d);
{
    uint32_t n[2];
    memcpy(n, &d, 8);
    return n[0];
}

根据字节顺序和其他平台细节,您的里程可能会有所不同。