管理 C++ 的规则是什么?单双精度混合计算?
例如,这些变量:
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
如果您有:
...那么像
f * d
这样的算术表达式会将两个操作数提升为更大的类型,在本例中为double
。因此,表达式
a * (b + c) * d
计算结果为double
,然后存储在result
中,它也是一个双
。进行这种类型提升是为了避免意外的精度损失。有关详细信息,请阅读有关常见算术转换< /a>.
If you have:
...then an arithmetic expression like
f * d
will promote both operands to the larger type, which in this case isdouble
.So, the expression
a * (b + c) * d
evaluates to adouble
, and is then stored inresult
, which is also adouble
. This type promotion is done in order to avoid accidental precision loss.For further information, read this article about the usual arithmetic conversions.
您必须区分类型转换和值转换。 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.
您有括号来分隔浮动加法。
所以它将 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<>()
;按照操作顺序,每个子表达式都会转换为它的类型(不确定这里的术语,也许是主导类型?)。 double 优于 float,因此:
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:
在您的示例中,当计算右侧公式时,所有
float
类型都将类型提升为double
。至于它们是如何转换的:我所读到的关于浮点运算的内容是,大多数当代硬件在特殊硬件寄存器中使用扩展精度(80 位)长双精度数来执行 FP 运算(至少这是我对现代 Intel x86 的记忆) /x87 处理器)。据我了解,
float
和double
是通过特殊的FP指令在硬件中进行类型提升的(如果我错了,有人纠正我)。In your example, all the
float
types are type-promoted todouble
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
anddouble
are type-promoted IN HARDWARE via special FP instructions (someone correct me if I'm wrong).浮点数将被上转换为双精度数。显式转换值。
也就是说,如果你想要双倍的结果,你会写:
它总是值得明确的。它避免了像这样的误解,对于任何试图完全按照您的意思使用您的代码的人来说,这都是显而易见的。
The floats will be upconverted to doubles. Explicitly cast the values.
ie if you want double as your result you would write:
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.
所有操作都在相同类型的对象上完成(假设正常算术运算)。
如果您编写的程序使用不同类型,那么编译器将自动升级 ONE 参数,以便它们相同。
在这种情况下,浮点数将升级为双精度数:
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: