C ++:隐式类型转换

编程入门 行业动态 更新时间:2024-10-14 02:18:55
本文介绍了C ++:隐式类型转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我有点困惑隐式类型转换。给定以下程序

float x = 4.23423451; double y = 4.23423451; float z = 101.9876; float res1 = x * z; float res2 = y * z; std :: cout<< res1& res2< res1<< &<< res2<< std :: endl; std :: cout<< 相等< (res1 == res2)< std :: endl;

输出为

res1& res2 431.839& 431.839 equality 1

我的问题是对于任何值

res2 = y * z;

变量y是否类型转换为float或变量

请参阅我的意见。

z 的中间表达式将扩展为 double ,因此 y * z 将是一个 double 表达式。然后,隐式变窄转换将其转换为 float ,以存储在 res2 中。这同样缩小适用于 res1 。

许多二进制运算符期望操作数算术或枚举类型以类似的方式导致转换和产生结果类型。目的是产生一个共同的类型,这也是结果的类型。这种模式称为通常的算术转换,定义如下:

...

  • 否则,如果任一操作数 double ,则另一个将转换为 double 。
  • 否则,如果任一操作数 float ,另一个将转换为 float 。

...

b $ b

但是,这不能保证平等。

> res1 不一定等同于 res2 - 它高度依赖于 float 和 double 。这两个文本可能甚至不相等 - 4.23423451f 甚至不需要等同于 4.23423451 。您不能确定 static_cast< double>(static_cast< float>(4.23423451))将等于 4.23423451 。

请参阅§ 5.17¶ 3作业和复合赋值运算符[expr.ass] p>

如果左操作数不是类类型,则表达式被隐式转换(第4条)为左操作数的cv非限定类型。

§ 4个标准转换[conv] 说明如下:

标准转换是具有内置含义的隐式转换。第4节列举了全部这样的转换。 标准转换序列是以下列顺序的标准转换序列:

...

  • 以下集合中的零个或一个转换:积分促销,浮点提升,积分转换,浮点转换,浮点积分转换,指针转换,指向成员转换的指​​针,

详情请参阅 4.6浮点宣传[conv.fpprom] ,

  • 类型 float 可以转换为 double 类型的prvalue。

  • ...和 4.8浮点转换[conv.double] ,

  • 浮点类型的prvalue可以转换为另一个浮点类型的prvalue。如果源值可以在目标类型中精确表示,则转换的结果是精确表示。如果源值在两个相邻的目标值之间,则转换的结果是这些值中的任一个的实现定义的选择。

  • 允许作为浮点促销的转化被排除在浮点数转换集合之外。

    这里的问题是我们有多种情况,我们的转换不是促销而是缩小到潜在的更低精度类型( double 到 float )。

    基本上,任何时候你转换 double 到 float ,你可能会失去精度。 / p>

    I am bit confused about implicit type conversion. Given the following program

    float x = 4.23423451; double y = 4.23423451; float z = 101.9876; float res1 = x * z; float res2 = y * z; std::cout << "res1 & res2 " << res1 << " & " << res2 << std::endl; std::cout << "equality " << (res1 == res2) << std::endl;

    The output was

    res1 & res2 431.839 & 431.839 equality 1

    My question is "Will the equality be always true for any value of x, y & z (x = y) and also for any compiler?"

    In

    res2 = y * z;

    Will the variable "y" be type-casted to float or variable "z" be type-casted to double?

    解决方案

    See my comments.

    This is well-defined. The intermediate expression for z will undergo widening into double, so y * z will be a double expression. An implicit narrowing conversion will then convert it to float for storing in res2. This same narrowing applies to res1.

    This is reflected by §5¶9 Expressions [expr] of the C++11 standard.

    Many binary operators that expect operands of arithmetic or enumeration type cause conversions and yield result types in a similar way. The purpose is to yield a common type, which is also the type of the result. This pattern is called the usual arithmetic conversions, which are defined as follows:

    ...

    • Otherwise, if either operand is double, the other shall be converted to double.
    • Otherwise, if either operand is float, the other shall be converted to float.

    ...

    This, however, does not sure that the equality will hold.

    That being said, res1 need not necessarily be equivalent to res2 -- it is highly dependent on the precision of float and double in the environment. The two literals could potentially not even be equal -- 4.23423451f not need even be equivalent to 4.23423451. You can not be sure that static_cast<double>(static_cast<float>(4.23423451)) will be equal to 4.23423451.

    See §5.17¶3 Assignment and compound assignment operators [expr.ass].

    If the left operand is not of class type, the expression is implicitly converted (Clause 4) to the cv-unqualified type of the left operand.

    §4 Standard conversions [conv] states as follows:

    Standard conversions are implicit conversions with built-in meaning. Clause 4 enumerates the full set of such conversions. A standard conversion sequence is a sequence of standard conversions in the following order:

    ...

    • Zero or one conversion from the following set: integral promotions, floating point promotion, integral conversions, floating point conversions, floating-integral conversions, pointer conversions, pointer to member conversions, and boolean conversions.

    As elaborated in §4.6 Floating point promotion [conv.fpprom],

  • A prvalue of type float can be converted to a prvalue of type double. The value is unchanged.
  • This conversion is called floating point promotion.
  • ... and §4.8 Floating point conversions [conv.double],

  • A prvalue of floating point type can be converted to a prvalue of another floating point type. If the source value can be exactly represented in the destination type, the result of the conversion is that exact representation. If the source value is between two adjacent destination values, the result of the conversion is an implementation-defined choice of either of those values. Otherwise, the behavior is undefined.

  • The conversions allowed as floating point promotions are excluded from the set of floating point conversions.

  • The problem here is that we have multiple cases where our conversion is not promotion, but rather narrowing to a potentially lower-precision type (double to float).

    Essentially, any time you convert double to float, you may potentially lose precision.

    更多推荐

    C ++:隐式类型转换

    本文发布于:2023-07-14 10:15:36,感谢您对本站的认可!
    本文链接:https://www.elefans.com/category/jswz/34/1104079.html
    版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
    本文标签:类型   隐式

    发布评论

    评论列表 (有 0 条评论)
    草根站长

    >www.elefans.com

    编程频道|电子爱好者 - 技术资讯及电子产品介绍!