2016-10-14 80 views
0

我試試下面的代碼:溢出時UINT64 = UINT8 * UINT8

UINT a = 32768; 
UINT b = 32768; 
UINT64 c = a * b * 4; // c = 0, overflow...; 
UINT64 d = (UINT64)a * (UINT64)b * 4; // d = 4294967296, the right answer; 

爲什麼UINT64 C = A * B * 4會溢出?

我覺得A * B * 4首先會保持在一個溫度UINT值,然後將分配給參數c?這樣對嗎?

我想搜索谷歌的一些提示,但我不知道我應該使用什麼關鍵詞。

由於

+0

[算術運算符(http://en.cppreference.com/w/cpp/language/operator_arithmetic) – Danh

+1

你的假設是正確的。整個行動不是原子的。 –

+0

如果您使用標準類型,這將有所幫助。什麼是UINT? – juanchopanza

回答

2

同樣的緣由,

double x=1/2; 

將是0,但

double y=double(1)/2; 

將是0.5

除非你強迫你的操作數所需的最終類型之一,一切都將在任何操作數後,才轉換爲目標類型的最大的精密計算。

在你的情況下,一切都以32位精度計算,溢出發生在之前,轉換爲64bits。

0

在C UINT64,它的右手側被自動指定爲UINT,因爲A和B都是UINT,之後將其分配的答案爲C(已溢出)。爲了確保這不會發生,c中的一個變量也必須是uint64,然後它不會溢出。 這就是爲什麼int64 d的作品,因爲它也被分配。

0

你的假設是正確的。由於a和b是UINT值,因此操作以UINT形式完成,並且在* 2 * 32期間它將在32位UINT中以0形式溢出。結果只會被轉換爲UINT64。

3
UINT a = 32768; 
UINT b = 32768; 
UINT64 c = a * b * 4; 

被評估爲

UINT a = (UINT) 32768; 
UINT b = (UINT) 32768; 
UINT64 c = (UINT) a * (UINT) b * (int) 4; 

UINT沒有足夠的空間來存儲UINT*UINT,你會得到一個溢出。

您可以通過鑄造UINT S的一個至UINT64像這樣解決這個問題:

UINT64 c = (UINT64) a * b * 4;