如何通过乘法避免整数溢出而不进行类型转换?

时间:2012-11-10 03:43:16

标签: c integer-overflow

请考虑以下代码:

unsigned int var1 = 4294967295;

unsigned int var2 = 1000000;

unsigned int var3;

var3 = some_expression - (var1*var2)/some_expression;

错误:

在var3的表达式中,值为:

(var1 * var2)被截断为32位整数(因为它是通过乘以2个32位整数得到的)。

可能的修复:

var3 = some_expression - ((unsigned long int)var1*var2)/some_expression;

问题:

Solaris NOT 接受此类型转换&抛出以下错误:

“转换为请求的非标量类型”

我可以在没有类型转换的情况下修复此问题吗?

3 个答案:

答案 0 :(得分:1)

介绍一个中间变量:

unsigned int var1 = 4294967295U;
unsigned int var2 = 1000000U;
unsigned int var3;

{
  unsigned long int vartmp = var1;
  vartmp *= var;

  var3 = some_expression - vartmp/some_expression;
}

答案 1 :(得分:0)

必须有一个更好的方法,但我理论中的数字表示在var1 var2some_expression找到共同因素,并尝试取消我们的共同因素。这个解决方案取决于他们分享一些甚至可能不会发生的因素。

我能想到的唯一另一件事就是做一些模拟的long long大型int数学,这可能会变得混乱。

答案 2 :(得分:0)

没有明确的类型转换,可以将其作为

完成
unsigned long tmp = var1;
var3 = some_expression - (tmp * var2) / some_expression;

(假设unsigned long的类型大于unsigned int),这与“可能的修复”几乎相同。

但是,您的“可能修复”应该可以自行解决。我不相信任何自尊的编译器会在响应您的表达式时生成此类错误消息。发布产生此错误消息的实际代码。

事实上,我记得一两天前在这里问过的一个非常相似的问题。在这种情况下,代码的作者被类型转换为某些类型定义类型,如UL64,认为它代表unsigned long int,而实际上typedef指的是struct类型。这导致了错误消息。