frexp和ldexp之间的差异

Discrepancy between frexp and ldexp

本文关键字:之间 ldexp frexp      更新时间:2023-10-16

考虑以下内容:

#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 %fn",ldexp_signif);
printf ("The exponent INPUT is %fn",ldexp_expo);
printf ("The float OUTPUT is %fnn",ldexp_output);
// get sig and expo from float
frexp_signif = frexp (frexp_input , &frexp_expo);
printf ("The float INPUT is %fn",frexp_input);
printf ("the exponent OUTPUT is %in",frexp_expo);
printf ("The significand OUTPUT is %fn",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的浮点输入不同?我找到了这篇文章,但那篇文章没有回答我的问题。我也看到了这一点,它指出浮点计算是不准确的。控制台的输出仅用于演示目的,有效位和指数将从使用单精度浮点格式编写的游戏数据文件中读取,然后用于显示数据,它不会用于任何潜在的生命威胁,如医疗或军事应用,我应该照原样看,还是寻找更准确的解决方案?

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

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

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

使用%f打印该值时显示"0.545528",这是一个不同数字的十进制数字,因为实际值0.54552845837963870323505943815689533948983114296875已四舍五入显示。

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

当使用ldexp将其乘以212时,结果为2234.48268800000005285255610942840576171875。

%f打印该值会显示"2234.482688",同样是因为该数字是四舍五入显示的。

总结:ldexp没有被赋予frexp产生的有效位。frexp产生的有效位为0.5455284583796387032350594381568953394898314296875,但给ldexp的有效位是0.5455280000000001290345608140341937541961669921875。这些是不同的,所以得到了不同的结果。

观察有效位在其第七个有效数字附近发生变化,缩放值在其第7个有效数字周围发生变化。