管理 C++ 的规则是什么?单双精度混合计算?

发布于 2024-10-03 15:26:34 字数 202 浏览 0 评论 0原文

例如,这些变量:

result (double)
a (double)
b (float)
c (float)
d (double)

一个简单的计算:

result = a * (b + c) * d

如何以及何时转换类型以及如何确定每次计算执行的精度?

For example, these variables:

result (double)
a (double)
b (float)
c (float)
d (double)

A simple calculation:

result = a * (b + c) * d

How and when are the types converted and how do I figure out what precision each calculation is performed at?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

捶死心动 2024-10-10 15:26:35

如果您有:

float f;
double d;

...那么像 f * d 这样的算术表达式会将两个操作数提升为更大的类型,在本例中为 double

因此,表达式 a * (b + c) * d 计算结果为 double,然后存储在 result 中,它也是一个。进行这种类型提升是为了避免意外的精度损失。

有关详细信息,请阅读有关常见算术转换< /a>.

If you have:

float f;
double d;

...then an arithmetic expression like f * d will promote both operands to the larger type, which in this case is double.

So, the expression a * (b + c) * d evaluates to a double, and is then stored in result, which is also a double. This type promotion is done in order to avoid accidental precision loss.

For further information, read this article about the usual arithmetic conversions.

春庭雪 2024-10-10 15:26:35

您必须区分类型转换和值转换。 C++ 标准(也包括 C)允许以扩展精度进行浮点计算。

“浮点操作数的值和浮点表达式的结果可以用比类型所需的更高的精度和范围来表示;类型不会因此而改变。”

作为类型,b + c 是两个浮点数的加法。结果是一个浮点数。然后,结果类型提升为 double,并且两次乘法以 double 形式完成,结果为 double。

但是,允许实现使用双精度(或更高精度)执行所有计算,包括 b + c。
事实上,我使用 Visual C++ 进行了尝试,它使用 x86 上可用的 80 位浮点堆栈完成了所有计算。

You have to differentiate between type conversion and value conversion. The C++ standard (C as well) allows floating-point calculations to be done at extended precision.

"The values of the floating operands and the results of floating expressions may be represented in greater precision and range than that required by the type; the types are not changed thereby."

As types, b + c is an addition of two float(s). The result is a float. The result is then type promoted to a double and the two multiplications are done as doubles with a result of double.

However, an implementation is allowed to do all the calculations, including b + c, using doubles (or higher precision).
Indeed, I tried it out using Visual C++ and it did all the calculations using the 80-bit floating-point stack available on x86.

薄暮涼年 2024-10-10 15:26:35

您有括号来分隔浮动加法。
所以它将 b + c 作为 float + float。将其转换为双精度以保持最大精度,然后乘以双精度值。

但是,在您想要控制转换而不是猜测的情况下:
使用static_cast<>()

You have parenthesis delimiting the float adition.
So it would do b + c as float + float. Convert this to double for keeping largest precision, then multiply the double values.

However in such case where you want control over conversions, and not guessing:
use static_cast<>();

魂牵梦绕锁你心扉 2024-10-10 15:26:35

按照操作顺序,每个子表达式都会转换为它的类型(不确定这里的术语,也许是主导类型?)。 double 优于 float,因此:

(b + c) // this is evaluated as a float, since both b and c are floats
a * (b + c) // this is evaluated as a double, since a is a double
a * (b + c) * d // this is evaluated as a double, since both "a * (b + c)" and d are doubles

Following order of operations, each sub-expression is converted to the type of it's (not sure of the term here, dominant perhaps?) type. double is dominant over float, so:

(b + c) // this is evaluated as a float, since both b and c are floats
a * (b + c) // this is evaluated as a double, since a is a double
a * (b + c) * d // this is evaluated as a double, since both "a * (b + c)" and d are doubles
贱贱哒 2024-10-10 15:26:35

在您的示例中,当计算右侧公式时,所有 float 类型都将类型提升为 double

至于它们是如何转换的:我所读到的关于浮点运算的内容是,大多数当代硬件在特殊硬件寄存器中使用扩展精度(80 位)长双精度数来执行 FP 运算(至少这是我对现代 Intel x86 的记忆) /x87 处理器)。据我了解,floatdouble是通过特殊的FP指令在硬件中进行类型提升的(如果我错了,有人纠正我)。

In your example, all the float types are type-promoted to double when the right-side formula is evaluated.

As for how they're converted: What I've read regarding floating point operations is that most contemporary hardware perform FP operations using extended-precision (80 bit) long doubles in special hardware registers (at least that's what I remember about modern Intel x86/x87 processors). As I understand it, float and double are type-promoted IN HARDWARE via special FP instructions (someone correct me if I'm wrong).

懷念過去 2024-10-10 15:26:35

浮点数将被上转换为双精度数。显式转换值。

也就是说,如果你想要双倍的结果,你会写:

result = a * double( b + c ) * d;

它总是值得明确的。它避免了像这样的误解,对于任何试图完全按照您的意思使用您的代码的人来说,这都是显而易见的。

The floats will be upconverted to doubles. Explicitly cast the values.

ie if you want double as your result you would write:

result = a * double( b + c ) * d;

It is ALWAYS worth being explicit. It gets round misunderstandings like this and it is INSTANTLY obvious to anyone trying to use your code exactly what you mean.

夜访吸血鬼 2024-10-10 15:26:34

所有操作都在相同类型的对象上完成(假设正常算术运算)。

如果您编写的程序使用不同类型,那么编译器将自动升级 ONE 参数,以便它们相同。

在这种情况下,浮点数将升级为双精度数:

result      = a * (b + c) * d

float  tmp1 = b + c;            // Plus operation done on floats.
                                // So the result is a float

double tmp2 = a * (double)tmp1; // Multiplication done on double (as `a` is double)
                                // so tmp1 will be up converted to a double.

double tmp3 = tmp2 * d;         // Multiplication done on doubles.
                                // So result is a double

result      = tmp3;             // No conversion as tmp3 is same type as result.

All operations are done on objects of the same type (assuming normal arithmetic operations).

If you write a program that uses different types then the compiler will auto upgrade ONE parameter so that they are both the same.

In this situations floats will be upgraded to doubles:

result      = a * (b + c) * d

float  tmp1 = b + c;            // Plus operation done on floats.
                                // So the result is a float

double tmp2 = a * (double)tmp1; // Multiplication done on double (as `a` is double)
                                // so tmp1 will be up converted to a double.

double tmp3 = tmp2 * d;         // Multiplication done on doubles.
                                // So result is a double

result      = tmp3;             // No conversion as tmp3 is same type as result.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文