Выражение вычисляется неправильно

#c #overflow

#c #переполнение

Вопрос:

Я написал этот код, который правильно оценил все, вплоть до этого конкретного набора чисел :

 #include <cmath>

int n1 = 187972 ;
int n2 = 12026 ;
double a = 0.002 ;
int partial = round((n1*n2)*a) ;
int result = n1 - partial ;
  

результат возвращается программой как 4256804, что совершенно неверно. Я полагаю, что я ошибаюсь, но я не вижу, как.

Комментарии:

1. Похоже на n1*n2 переполнение int .

2. 2260551272 > 2147483647 (он же INT_MAX )

3. Обратите внимание, что есть несколько способов избежать переполнения: godbolt.org/z/6xsKW6

Ответ №1:

как и предлагалось в комментариях, результат правильный, потому что n1 * n2 переполняет значение int max, генерируя отрицательное число в результате переполнения

на самом деле -2034416024

вот ideone, чтобы вы могли проверить

https://ideone.com/NIGCmx

решением могло бы быть использование длинных чисел вместо

Комментарии:

1. Я не уверен, что вы подразумеваете под «правильным». Переполнение int — это UB. Перенос не требуется (по крайней мере, до c 20 iirc).

Ответ №2:

 #include <cmath>

int n1 = 187972 ;
int n2 = 12026 ;
double a = 0.002 ;
long long partial = round((n1*n2)*a) ;   // new
long long result = n1 - partial ;   // new