C 提取双精度字符中最有意义的单词
我想获取C 提取双精度字符中最有意义的单词,c,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
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);
}
像这样:
uint32_t msw(double d);
{
uint32_t n[2];
memcpy(n, &d, 8);
return n[0];
}
根据终端和其他平台的具体情况,您的密码可能会有所不同。如下所示:
uint32_t msw(double d);
{
uint32_t n[2];
memcpy(n, &d, 8);
return n[0];
}
根据endianness和其他平台细节,您的密码可能会有所不同。类型转换
值
到无符号长
只需将其截断为整数,它不会产生无符号长
中的双
的内存表示形式。改用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;
}
或者,正如所建议的,如果目标体系结构对整数和浮点数使用相同的endianness(它几乎总是这样做):
将
值
类型转换为无符号长
只需将其截断为整数,它不会产生无符号长
中的双精度
的内存表示形式。改用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;
}
或者,正如所建议的,如果目标体系结构对整数和浮点数使用相同的endianness(它几乎总是这样做):
您需要引用相同的内存区域,而不仅仅是强制转换值。在C99(或大约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世纪初编译器开始采用它后,为避免严格的别名问题而推荐的类型转换方法之一。请参阅此处的较长文字:您需要引用相同的内存区域,而不仅仅是强制转换值。在C99(或大约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世纪初编译器开始采用它后,为避免严格的别名问题而推荐的类型转换方法之一。在这里看到一个较长的写: <代码> RealTytCase和
联合转换{double d;无符号字符u[sizeof(double)];};并集x;x、 d=-42.24;对于(intk=0;k
尝试这个“解决方案”:联合转换{double d;无符号字符u[sizeof(double)];};并集x;x、 d=-42.24;对于(intk=0;k这是未定义的行为,非@KerrekSB:C11脚注95(C99+TC3中的脚注82):“如果用于读取联合对象内容的成员与上次用于在对象中存储值的成员不同,则该值的对象表示的适当部分将重新解释为6.2.6中所述的新类型中的对象表示(有时称为“类型双关”的过程)。”。“这是未定义的行为,非@KerrekSB:C11脚注95(C99+TC3中的脚注82):“如果用于读取联合对象内容的成员与上次用于在对象中存储值的成员不同,则该值的对象表示的适当部分将重新解释为6.2.6中所述的新类型中的对象表示(有时称为“类型双关”的过程)。”。“最好将memcpy存储到uint64\u t
,然后返回移位32的值;这样你就不需要处理endianness(除非你的机器对浮点数据的endianness与对整型数据的endianness不同,这很奇怪,但也有可能)。@StephenCanon对,修正了这一点。最好将内存复制到uint64\t
,然后返回移位32的值;这样,您就不需要处理endianness(除非您的机器对浮点数据的endianness与对整数数据的endianness不同,这很奇怪,但也有可能)。@StephenCanon-Right,修复了这个问题。