当浮点数分配给长双精度浮点数的值时会发生什么? [英] What happens to the value of a floating point number when it's assigned to a long double?

查看:138
本文介绍了当浮点数分配给长双精度浮点数的值时会发生什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:我已经意识到我正在使用 long double 不只是 double 确实)。我还在下面添加了一个例子,用于再现问题中的错误。

Edit: I've realised that I'm working with the type long doubleand not just double which does make a difference. I've also added an example from my program below that reproduces the error in question.

+11并使用GCC进行编译。

Note: I'm currently working in C++11 and using GCC to compile.

我处理的情况下,结果在以下两个计算之间变化:

I'm dealing with a situation where the result varies between the below two calculations:

value1 = x * 6.0;







double six = 6.0;
value2 = x * six;







value1 != value2

其中上述所有变量类型 long double

Where all variables above are of type long double.

基本上,当我在实际计算中使用6.0时,我写了一行代码,给我一个不正确的答案。然而,如果我将一个类型为long double的变量赋给6.0,那么在计算中使用该变量,我得到正确的结果。

Essentially, I wrote a line of code that gives me an incorrect answer when I use 6.0 in the actual calculation. Whereas, if I assign 6.0 to a variable of type long double first then use that variable in the calculation I receive the correct result.

我理解浮点运算的基本知识,并且我想明显的是,当分配给长double类型时,某些事情发生在6.0的位。

I understand the basics of floating point arithmetic, and I guess it's obvious that something is happening to the bits of 6.0 when it is assigned to the long double type.

从我的实际程序中取样(我离开了计算以确保错误是可重现的):

Sample from my actual program (I left the calculation as is to ensure the error is reproducible):

#include <iomanip>
#include <math.h>

long double six = 6.0;
long double value1;
long double value2;

value1 = (0.7854 * (pow(10, 5)) * six * (pow(0.033, 2)) * 1.01325 * (1.27 * 11.652375 / 1.01325 - 1.0));
value2 = (0.7854 * (pow(10, 5)) * 6.0 * (pow(0.033, 2)) * 1.01325 * (1.27 * 11.652375 / 1.01325 - 1.0));

std::cout << std::setprecision(25) << value1 << std::endl;
std::cout << std::setprecision(25) << value2 << std::endl;

其中输出为:

7074.327896870849993415931
7074.327896870850054256152

计算只保持精度高达一定数量的位(因此设置这样高的精度不应该影响结果,例如在15-17位数之后,如果数字变化但是不幸的是,这 会影响我的计算)

Also, I understand how floating point calculations only hold precision up to a certain number of bits (so setting such high precision shouldn't effect results, e.g. after 15-17 digits it should really matter if numbers vary but unfortunately this does affect my calculation).

问题:为什么上述两个代码段会产生(略微)不同的结果?

Question: Why are the above two code segments producing (slightly) different results?

注意:我不是简单地将这两个数字与 == 接收 false 。我刚刚使用 setprecision 打印出来,并检查每个数字。

推荐答案

这里的问题我相信是促销之一。

The problem here I believe is one of promotion.

long double six = 6.0;
long double value1;
long double value2;

value1 = (0.7854 * (pow(10, 5)) * six * (pow(0.033, 2)) * 1.01325 * (1.27 * 11.652375 / 1.01325 - 1.0));
value2 = (0.7854 * (pow(10, 5)) * 6.0 * (pow(0.033, 2)) * 1.01325 * (1.27 * 11.652375 / 1.01325 - 1.0));

看看第二个计算,我们注意到表达式中的每个项都是 double 。这意味着整个表达式将被计算为 double precision

Looking at the second calculation we notice that every term in the expression is type double. This means the whole expression will be evaluated to double precision.

但是, c $ c> six ,类型为 long double 。这将导致整个表达式以较高的精度计算 long double

However the first calculation contains the variable six that is of type long double. This will cause the entire expression to be calculated at the higher precision of a long double.

在计算的精度很可能是差异的原因。第一个表达式的整个提升 long double 精度,但第二个计算只计算 double precision。

So this difference in the calculation's precision is likely the cause of the discrepancy. The whole of the first expression is promoted to long double precision but the second calculation is calculated only to double precision.

事实上,对代码的简单更改可以证明这一点。如果我们将 6.0 的类型从 double 更改为 long double 通过写 6.0L ,我们将得到相同的结果,因为两个表达式现在计算为相同的精度:

In fact a simple change to the code can prove this. If we change the type of the term 6.0 from double to long double by writing 6.0L we will get identical results because both expressions are now calculated to the same precision:

value1 = (0.7854 * (pow(10, 5)) * six * (pow(0.033, 2)) * 1.01325 * (1.27 * 11.652375 / 1.01325 - 1.0));
value2 = (0.7854 * (pow(10, 5)) * 6.0L * (pow(0.033, 2)) * 1.01325 * (1.27 * 11.652375 / 1.01325 - 1.0));

这篇关于当浮点数分配给长双精度浮点数的值时会发生什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆