C++ 位设置为浮点或双值c++;
我有两个IEEE754二进制表示位集,浮点(32位)和双精度(64位)。C++ 位设置为浮点或双值c++;,c++,floating-point,bitset,C++,Floating Point,Bitset,我有两个IEEE754二进制表示位集,浮点(32位)和双精度(64位)。 如何将此位集转换为实数浮点数或双数?使用bitset::to_ullong()和memcpy()位。首先,一个位不能简单地表示一个位。这样一种表述有很多内容。假设给您一个位集变量:param,您想将其转换为浮点。要保证此转换有效,您需要确保: param.size()==sizeof(float)*字符位 从中编码的param与endian::native numeric\u limits::is\u iec559为真
如何将此位集转换为实数浮点数或双数?使用
bitset::to_ullong()
和memcpy()
位。首先,一个位不能简单地表示一个位。这样一种表述有很多内容。假设给您一个位集
变量:param
,您想将其转换为浮点
。要保证此转换有效,您需要确保:
param.size()==sizeof(float)*字符位
- 从中编码的
与param
endian::native
为真numeric\u limits::is\u iec559
- 编码
的基数与param
numeric\u limits::radix
sizeof(unsigned long)==sizeof(float)
和sizeof(unsigned long)==sizeof(double)
):
double foo(常量位集和参数){
const auto val=param.to_ullong();
双重结果;
memcpy(&result,&val,sizeof(double));
返回结果;
}
浮点foo(常量位集和参数){
const auto val=参数至_ulong();
浮动结果;
memcpy(&result,&val,sizeof(float));
返回结果;
}
<代码> > p>这里是一个不依赖于IEEE-75类型的C++实现的解决方案。
设s
为位集的第一位
让e
分别为32位或64位的下一个8位或11位
让f
分别为剩余的23位或52位
设Ebias
分别为127或1023
设Emax
分别为255或2047
设Fscale
分别为0x1p-23或0x1p-52
然后,此代码返回解释为IEEE-754基本二进制浮点对象的位集值:
// Interpret the sign.
double S = s ? -1 : +1;
// Classify the exponent.
if (e == 0)
// The value is zero or subnormal.
return S * std::ldexp(f*Fscale, 1-Ebias);
else if (e < eMax)
// The value is normal.
return S * std::ldexp(1 + f*Fscale, e-Ebias);
else
// The value is NaN or infinite.
if (f == 0)
// The value is infinite.
return S * INFINITY;
else
// The value is a NaN.
return NAN;
//解释符号。
双S=S-1 : +1;
//对指数进行分类。
如果(e==0)
//该值为零或低于正常值。
返回S*std::ldexp(f*Fscale,1-Ebias);
else if(e
这不会将NAN中的所有位(包括符号位)设置为与位集中的精确位匹配。没有便携的方法可以做到这一点;通常需要通过使用字符类型来将代码位复制到<代码>浮点或双对象,或者通过字符类型进行其他复制,这要求C++实现采用IEEE-75 4的<代码>浮点<代码>或<代码>双< /代码>类型。当然,上面的C++实现需要支持代码> No> <代码>和<代码>无穷大>代码>,C++实现中的浮点类型能够表示值。注意,只适用于不保证浮动的格式的系统。(可能是endianness,可能只是完全不同的格式)。如果您需要支持其他系统,则需要进行实际转换。@FireLancer我认为您的说法不正确。中间ulong
将简单地存储位集拥有的任何内容,我们已经知道它在IEEE754中。@BartekBanachewicz,如果代码运行的系统不是IEEE754,则结果是float
或双 >代码> MycPy将不具有期望值。没错。<代码> ISHIEC55 9/代码>不是一个常用的指示符。<代码> ISHIEC55 9/<代码>应该是真的,如果类型包括算术和其他行为符合IEC 60559/IEEE 754。然而,许多C++实现使用IEEE-75格式,但不使用。符合其算术要求,因此不设置is_iec559
。因此is_iec559
不能作为是否使用IEEE-754格式的指标。@EricPostpischil是的……但关键的一点是,不是IEEE 754的浮点从未设置此值。我将通过演示如何uld提取位以重新格式化一个不符合IEEE 754的浮点…但后来我意识到可能没有人会看到这个答案,因此没有理由将其扩展到最简单的用例之外。
// Interpret the sign.
double S = s ? -1 : +1;
// Classify the exponent.
if (e == 0)
// The value is zero or subnormal.
return S * std::ldexp(f*Fscale, 1-Ebias);
else if (e < eMax)
// The value is normal.
return S * std::ldexp(1 + f*Fscale, e-Ebias);
else
// The value is NaN or infinite.
if (f == 0)
// The value is infinite.
return S * INFINITY;
else
// The value is a NaN.
return NAN;