2012-11-10 27 views
3

请考虑下面的代码:如何通过乘法避免整型溢出而无需类型转换?

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确实接受这种类型转换&引发以下错误:

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

我能否解决此问题而不进行类型转换?

+4

没有什么是错误的。无论Solaris编译器是否损坏,请使用更好的编译器,或者'some_expression'中有错误,请向我们展示您的真实代码。 –

+0

为什么不首先避免溢出?一世。e首先进行分割,然后乘法 - (var1/someExpression)* var2 – enhzflep

+1

@enhzflep通常,'var1/someExpression * var2'不会给出与'var1 * var2/someExpression'相同的答案,因为整数分割会截断。 –

回答

0

这里有一个更好的方法,但我的数字理论家说在var1var2some_expression找到共同的因素,并试图取消我们的共同因素。这个解决方案是以它们共享一些甚至可能不会发生的因素为条件的。

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

0

良好,没有明确的类型转换可以作为

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

(假设unsigned longunsigned int更大的类型),这几乎是同样的事情,你的“可能的修复程序”来完成。

但是,您的“可能的修复”应该自行工作。我不相信任何自尊心的编译器会产生这样的错误信息来回应你的表达。发布产生此错误消息的实际代码。

事实上,我记得一两天前在这里已经提出过非常类似的问题。在这种情况下,代码的作者是类似于类型定义的类型,如UL64认为它代表unsigned long int,而实际上typedef指的是struct类型。这导致了错误信息。

+1

如果隐式类型的铸造工作在显式不包含的情况下,我会感到震惊 –

+0

“unsigned long int tmp = var1;”会给出同样的错误。它几乎等同于在var3的表达式中进行类型转换。 –

+0

然后因为什么原因你在你的上下文中有'struct long'。您可能希望检查提供此错误的文件的预处理输出,以查看幕后编译器真正提供的内容。 @SandeepSingh – alk

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; 
} 
+0

谢谢,但我无法更改var1的数据类型。为了便于理解,我简化了这里的场景。在真实代码中,var1从返回类型为unsigned int的函数中绘制其值。改变var1的类型将会改变那里的错误。我希望也许有人可以用位运算符来解决这个问题。 –

+0

无论如何,为您的努力+1。 –

+0

请问我在哪种方式中将'var1'的类型更改为OP? @SandeepSingh – alk

相关问题