2016-10-14 5 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 с = A * B * 4 будет переполнение?

Я думаю, что a * b * 4 сначала сохранит значение UINT, а затем назначит параметру c? Это правильно?

Я хочу найти google для некоторого намека, но я не знаю, какое ключевое слово я должен использовать.

Благодаря

+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 бит, происходит переполнение до преобразование в 64 бит.

0

В uint64 С, это правая сторона автоматически назначается как UINT, потому что А и В оба UINT, после чего она назначает ответ с (уже переполнена). Чтобы этого не произошло, ОДНА из переменных в c также должна быть uint64, а затем она не будет переполняться. Вот почему int64 d работает, потому что он также был назначен.

0

Ваше предположение верно. Поскольку a и b являются значениями UINT, операция выполняется как UINT, а во время * b * 4, которая равна 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 с Ань UINT64 как так:

UINT64 c = (UINT64) a * b * 4; 
Смежные вопросы