C ++隐式转换(有符号+无符号) [英] C++ Implicit Conversion (Signed + Unsigned)

查看:458
本文介绍了C ++隐式转换(有符号+无符号)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我了解到,对于隐式转换,如果我们有一个无符号类型的操作数和一个有符号类型的操作数,并且无符号操作数的类型与有符号操作数的类型相同(或大于),则该有符号操作数

I understand that, regarding implicit conversions, if we have an unsigned type operand and a signed type operand, and the type of the unsigned operand is the same as (or larger) than the type of the signed operand, the signed operand will be converted to unsigned.

因此:

unsigned int u = 10;  
signed int s = -8;

std::cout << s + u << std::endl;

//prints 2 because it will convert `s` to `unsigned int`, now `s` has the value
//4294967288, then it will add `u` to it, which is an out-of-range value, so,
//in my machine, `4294967298 % 4294967296 = 2`

我不了解的内容-我读到,如果有符号操作数的类型大于无符号操作数的类型:

What I don't understand - I read that if the signed operand has a larger type than the unsigned operand:


  • 如果所有无符号类型的值都适合较大的类型,则将无符号操作数转换为有符号类型

  • if all values in the unsigned type fit in the larger type then the unsigned operand is converted to the signed type

如果如果无符号类型不适合较大类型,则有符号操作数将转换为无符号类型

if the values in the unsigned type don't fit in the larger type, then the signed operand will be converted to the unsigned type

因此在以下代码中:

signed long long s = -8;
unsigned int u = 10;
std::cout << s + u << std::endl;

u 将被转换为带符号long long因为int值可以适合带符号的long long?

u will be converted to signed long long because int values can fit in signed long long??

如果是这种情况,在哪种情况下较小的类型值不能适合较大的类型?

If that's the case, in what scenario the smaller type values won't fit in the larger one?

推荐答案

标准中的相关报价:

5个表达式[expr ]


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

10 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:

[2关于相等类型或类型的子句等号的省略]

[2 clauses about equal types or types of equal sign omitted]


-否则,如果具有无符号整数类型的操作数的等级
大于或等于另一个操作数类型的等级,将带符号整数类型的操作数
转换为带符号整数类型的操作数
的类型。

— Otherwise, if the operand that has unsigned integer type has rank greater than or equal to the rank of the type of the other operand, the operand with signed integer type shall be converted to the type of the operand with unsigned integer type.

—否则,如果带符号整数类型的操作数
的类型可以表示带无符号整数类型的操作数的所有值
,则带符号无符号整数类型的操作数
应转换为带符号整数类型的
操作数的类型。

— Otherwise, if the type of the operand with signed integer type can represent all of the values of the type of the operand with unsigned integer type, the operand with unsigned integer type shall be converted to the type of the operand with signed integer type.

-否则,两个操作数都应被转换为与带符号整数类型的操作数
类型相对应的无符号整数类型。 p>

— Otherwise, both operands shall be converted to the unsigned integer type corresponding to the type of the operand with signed integer type.

让我们在以下系统上考虑上述3个子句的以下3种示例情况: int)< sizeof(long)== sizeof(long long) (很容易适应其他情况)

Let's consider the following 3 example cases for each of the 3 above clauses on a system where sizeof(int) < sizeof(long) == sizeof(long long) (easily adaptable to other cases)

#include <iostream>

signed int s1 = -4;
unsigned int u1 = 2;

signed long int s2 = -4;
unsigned int u2 = 2;

signed long long int s3 = -4;
unsigned long int u3 = 2;

int main()
{
    std::cout << (s1 + u1) << "\n"; // 4294967294
    std::cout << (s2 + u2) << "\n"; // -2 
    std::cout << (s3 + u3) << "\n"; // 18446744073709551614  
}

实时示例 ,并带有输出。

Live example with output.

第一个子句:等级相同的类型,因此 signed int 操作数将转换为 unsigned int 。这就需要进行值转换,(使用两个补码)给出打印的值。

First clause: types of equal rank, so the signed int operand is converted to unsigned int. This entails a value-transformation which (using two's complement) gives te printed value.

第二条子句:带符号的类型具有更高的排名,并且(在此平台上!)可以表示所有无符号类型的值,因此将无符号操作数转换为带符号类型,并且您得到-2

Second clause: signed type has higher rank, and (on this platform!) can represent all values of the unsigned type, so unsigned operand is converted to signed type, and you get -2

第三子句:带符号的类型再次具有更高的排名,但是(在此平台上!)不能表示所有无符号类型的值,因此两个操作数都将转换到 unsigned long long ,然后在有符号操作数上进行值转换之后,就得到了打印值。

Third clause: signed type again has higher rank, but (on this platform!) cannot represent all values of the unsigned type, so both operands are converted to unsigned long long, and after the value-transformation on the signed operand, you get the printed value.

注意,当无符号操作数足够大时(例如,在这些示例中为6),由于无符号整数溢出,最终结果将对所有3个示例给出2。

Note that when the unsigned operand would be large enough (e.g. 6 in these examples), then the end result would give 2 for all 3 examples because of unsigned integer overflow.

(已添加)请注意,当您对这些类型进行比较时,会得到更多意外结果。让我们考虑上面的示例1,其中<

(Added) Note that you get even more unexpected results when you do comparisons on these types. Lets consider the above example 1 with <:

#include <iostream>

signed int s1 = -4;
unsigned int u1 = 2;
int main()
{
    std::cout << (s1 < u1 ? "s1 < u1" : "s1 !< u1") << "\n";  // "s1 !< u1"
    std::cout << (-4 < 2u ? "-4 < 2u" : "-4 !< 2u") << "\n";  // "-4 !< 2u"
}

由于 u 显式地使> 2u 成为 unsigned 。比较 -4<的结果可能不是您期望的结果。 2 (在使用C ++编写时 -4< 2u ...

Since 2u is made unsigned explicitly by the u suffix the same rules apply. And the result is probably not what you expect when comparing -4 < 2 when writing in C++ -4 < 2u...

这篇关于C ++隐式转换(有符号+无符号)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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