2012-11-10 62 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

相關問題