Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 位设置为浮点或双值c++;_C++_Floating Point_Bitset - Fatal编程技术网

C++ 位设置为浮点或双值c++;

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为真

我有两个IEEE754二进制表示位集,浮点(32位)和双精度(64位)。
如何将此位集转换为实数浮点数或双数?

使用
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;