frexp和ldexp之间的差异

时间:2019-01-10 00:17:23

标签: c++ floating-point

请考虑以下内容:

#include <iostream>
//#include <math.h>
#include <cmath>
using namespace std;

int main(int argc, char **argv)
{
    double ldexp_signif = 0.545528;
    double ldexp_expo = 12;
    double ldexp_output = 0;

    double frexp_input = 2234.484565523;
    double frexp_signif = 0;
    int frexp_expo = 0;

    int n;

    // create float from sig and expo
    ldexp_output = ldexp (ldexp_signif , ldexp_expo);
    printf ("The significand INPUT is %f\n",ldexp_signif);
    printf ("The exponent INPUT is %f\n",ldexp_expo);
    printf ("The float OUTPUT is %f\n\n",ldexp_output);

    // get sig and expo from float
    frexp_signif = frexp (frexp_input , &frexp_expo);
    printf ("The float INPUT is %f\n",frexp_input);
    printf ("the exponent OUTPUT is %i\n",frexp_expo);
    printf ("The significand OUTPUT is %f\n",frexp_signif);

    // ==================================
    cout << endl << "=======================================" << endl << "Program completed and terminated successfully." << endl << "Press enter to exit";
    cin.ignore();
    return 0;
}

输出为:

The significand INPUT is 0.545528
The exponent INPUT is 12.000000
The float OUTPUT is 2234.482688

The float INPUT is 2234.484566
the exponent OUTPUT is 12
The significand OUTPUT is 0.545528

=======================================
Program completed and terminated successfully.
Press enter to exit

我想知道的是,当ldexp具有与frexp相同的有效数和指数时,为什么ldexp给出的浮点输出不同于frexp的浮点输入?我找到了this article,但该文章没有回答我的问题。我也saw this指出浮点计算不准确。控制台的输出仅用于演示目的,将从使用Single-precision floating-point format编写的游戏数据文件中读取有效值和指数,然后将其用于显示该数据,而不会将其用于任何可能的生命像医疗或军事应用一样,我应该按原样使用它还是寻找更准确的解决方案?

1 个答案:

答案 0 :(得分:3)

以下假设IEEE 754正在使用其基本的64位二进制浮点格式。

源文本double frexp_input = 2234.484565523;frexp_input初始化为2234.484565523000128450803458690643310546875。

然后frexp将指数设置为12并返回0.545528458379638703235059438156895339488983154296875。

%f打印该值将显示“ 0.545528”,它是另一个数字的十进制数字,因为实际值0.545528458379638703235059438156895339488983154296875进行了四舍五入显示。

在源文本double ldexp_signif = 0.545528;中使用该数字.545528时,它将ldexp_signif初始化为0.54552800000000001290345608140341937541961669921875。

使用ldexp将其乘以2 12 时,结果为2234.4826880000000528525565562942840576171875。

再次用%f打印该值将显示“ 2234.482688”,因为该数字已四舍五入以显示。

摘要:ldexp未获得frexp生成的有效位数。 frexp生成的有效位数为0.545528458379638703235059438156895339488983154296875,但赋予ldexp的有效位数为0.54552800000000001290345608140341937541961669921875。这些是不同的,因此获得了不同的结果。

观察到有效数字在其第七个有效数字附近发生了变化,而缩放值在其第七个有效数字附近发生了变化。