请解释这个奇怪的行为c ++乘以数字然后mod

时间:2017-04-27 15:55:30

标签: c++ type-conversion

我对c ++和i代码的经验较少,主要是在python中。在网上解决一些编程挑战时,有一部分代码我需要将两个数字相乘并用mod减少它。

v = (u*node) % 100000

其中u和node是int值,范围为1 - 100000.由于时间限制问题,我用c ++编写了我的代码。这就是我写的

long long v = (u * node) % 100000;

提交时我在所有测试用例中都遇到了运行时错误。我下载了失败的测试用例并在我的本地计算机上运行,​​我得到了完美的输出。

看完社论之后,我将这一行改为

long long v = u;
v = (v*node) % 100000;

并提交。我通过了所有测试用例。请任何人解释这两行之间的区别..

可变数据类型 -

int u
int node

3 个答案:

答案 0 :(得分:4)

因为unode都是int s,所以这个表达式

(u * node)

产生int结果。如果它溢出 - 意味着结果太大而不适合int - 太糟糕了。有符号整数溢出为undefined behavior,所有投注均已关闭。有可能,它会像环绕一样,但它也可以格式化你的硬盘。

当您u成为long long int时,相同的表达式会产生long long int结果。 node被乘数被隐式提升long long intintlong long int是一个扩展转换,所以它总是安全的),然后这两个long long int值会成倍增加。此操作不会溢出,因此您可以避免未定义的行为并获得正确的结果。

您也可以使用显式强制转换编写代码以避免声明新变量:

(static_cast<long long int>(u) * node)

请注意,您提升的值并不重要,结果将是相同的,因为其他值将被隐式提升,如上所述:

(u * static_cast<long long int>(node))

另一方面,这不起作用:

static_cast<long long int>(u * node)

因为它只加宽了乘法运算的结果在执行了乘法之后。如果该乘法溢出int类型,则已经太晚了。

这也是不起作用的原因 - 在结果被评估为long long后,int促销发生

long long v = (u * node)

答案 1 :(得分:2)

  

请有人解释这两行之间的区别。

第一行实际上是指:

long long v = (long long) (int * int % int);

所以,首先你将int乘以int, get overflow 截断为int ,mod,将int扩展为long long

下一行实际意思是:

long long v = (long long) int;
v = long long * int % int;

所以,首先将int扩展为long ,多个long by int, no overflow ,mod,赋值给long long

答案 2 :(得分:0)

可能你在第一种情况下遇到了溢出(u和v都是整数)。这是因为当乘法变量时,编译器会将结果保存在一个临时变量中,该变量与乘法中变量的最高类型(int,float,double等)的类型相同。所以,如果你乘以两个大整数,结果就会溢出。

您的修改有效,因为临时结果存储在很长的时间内,在示例中不会溢出。