C++ 表达式中的类型转换

C++ 表达式中的类型转换

简介

最近刷题经常遇到对结果取模,由于某些操作导致溢出。例如 MOD = 10e9 + 7

下列表达式

int hash = (base * base) % MOD // base * base  溢出

需要在表达式中加入强制类型转换。摘抄C++ Primer Plus 3.4.4 类型转换章节之表达式中的转换。

自动转换

整形提升(integral promotion): C++ 在计算表达式时,自动将 bool char unsigned char singed char short 转换为int。 例如true->1。由于int 是计算机最自然的类型,计算速度可能最快。

在表达式中,编译器通过按顺序查表进行转换:

  1. 如果一个操作数类型是 long double,将另一个操作数转换为long double
  2. 否则,如果一个操作数是double,将另一个操作数转换为double
  3. 否则,如果一个操作数是float,将另一个操作数转换为float
  4. 否则,说明操作数都是整型,执行整型提升
  5. 两个操作数均为有符号整型或者均为无符号整型,将级别低的转换成级别高的类型
  6. 如果两个操作数其中一个有符号整型另外一个无符号整型,且无符号整型级别比有符号操作数级别高,将有符号操作数转换为无符号操作数所属的类型
  7. 否则,如果有符号类型可表示无符号类型的所有可能取值,将无符号操作数转换为有符号操作数所属的类型
  8. 否则,将两个操作数都转换为有符号类型的无符号版本。

例如:对于 char + unsigned int 或者unsigned char + char ,执行4

对于6例如 unsigned long long + int 代码如下

#include <iostream>
#include <cmath>
#include <limits>
int main()
{
    using namespace std;
    cout << "size of int:" << sizeof(int) << endl;
    cout << "size of unsigned long long:" << sizeof(unsigned long long) << endl;
    int a = INT_MAX;
    cout << "MAX " << INT_MAX << endl;
    unsigned long long b = INT_MAX * 2ll; // 这里用到了5
    auto ret = a + b;
    cout  << ret << " " << sizeof(ret) << endl;
    return 0;
}
/*
size of int:4
size of unsigned long long:8
MAX 2147483647
*/

对于7,例如long long + unsigned int 代码如下

#include <iostream>
#include <cmath>
#include <limits>
int main()
{
    using namespace std;
    cout << "size of unsigned int:" << sizeof(unsigned int) << endl;
    cout << "size of long long:" << sizeof(long long) << endl;
    unsigned int a = 0xffffffff; // unsigned 最大值
    cout << "MAX " << a << endl;
    long long b = INT_MAX * 2ll;
    auto ret = a + b;
    cout  << ret << " " << sizeof(ret) << endl;
    return 0;
}
/*
size of unsigned int:4
size of long long:8
MAX 4294967295
8589934589 8
*/

强制类型转换

可以通过如下两种方式实现

(typeName) value // (long long )1
typeName (value) // long long (1)

总结

显然对于开始的例子,可以通过

using ll = long long;
int hash = ll(base) * base % MOD

解决

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页