C: два целых числа умножаются на отрицательное значение (пока не должно произойти переполнения)

В данный момент я изучаю C, и у нас есть довольно простое упражнение на умножение матриц, которое, кажется, хорошо работает для большинства тестовых случаев. Однако один случай не работает, и я уже сузил его до этого фрагмента кода, который не дает ожидаемого результата:

#include <stdio.h>

int main(){
    int a1 = 1261373;
    int b1 = 1261373;
    int a2 = 1669717;
    int b2 = 1293027;
    long mult1 = a1*b1;
    long mult2 = a2*b2;
    printf("mult1=%ld , mult2=%ld", mult1, mult2);
}

Вывод, который я получаю:

mult1=1923945609 , mult2=-1379386529

Вместо ожидаемого:

mult1=1591061845129, mult2=2158989163359

Очевидно, особенно со вторым результатом я сначала подумал о переполнении. Но на самом деле этого не должно происходить с такими маленькими числами, не так ли? Ввод определенно является целым числом (мы не можем это изменить), а вывод должен быть длинным, поэтому я не могу изменить типы данных, и я понятия не имею, как он получает отрицательное число для второго умножения или почему первый результат неправильно.

Любая помощь будет принята с благодарностью!


person Juliette    schedule 13.05.2017    source источник
comment
a1 * b1 — это int, которое вы затем конвертируете в long. Если вы хотите использовать умножение long, сначала приведите одно из них к long, как в (long)a1 * b1. (Кроме того, не полагайтесь на то, что long представляет какое-то определенное количество битов. Если вам нужно 64-битное целое число без знака, используйте uint64_t.)   -  person Ry-♦    schedule 13.05.2017
comment
Возможный дубликат Как умножить 32-битные целые числа в c   -  person Groo    schedule 13.05.2017
comment
Спасибо!!! Это решило проблему, я понятия не имел, что вам нужно сначала привести его к длинному, но теперь все тестовые случаи работают правильно :)   -  person Juliette    schedule 13.05.2017
comment
@ Райан, ты должен опубликовать это как ответ ...   -  person Erich Kitzmueller    schedule 13.05.2017
comment
обратите внимание, что long не является 64-битным на всех платформах, даже на платформах x64, см. это: stackoverflow.com/questions/6155784/   -  person niceman    schedule 13.05.2017
comment
Такие маленькие цифры. Времена меняются. Продукт, который вы пытаетесь вычислить, равен 2158989163359, что является 41-битным числом. Так что это будет работать на 64-битной машине, если вы сначала примените к long, как советовали другие комментарии/ответы. Но это все равно не будет работать на машине, где длина только 32 бита.   -  person Steve Summit    schedule 13.05.2017
comment
Если вы думаете о правиле, умножение двух int создает int в C, на самом деле это довольно легко запомнить. С другой стороны, целочисленное продвижение – это то, программисты, к сожалению, не знают (по моему мнению, из 10 случайно выбранных программистов на C 2 будут знать правила повышения), и это приведет к странным результатам, если вы не знаете об этом.   -  person Groo    schedule 13.05.2017
comment
@Groo Я знаю о целочисленном продвижении, и я все еще думаю, что иногда оно дает странные результаты. ;-)   -  person Andrew Henle    schedule 13.05.2017


Ответы (1)


Попробуй это

#include <stdio.h>

int main(){
    int a1 = 1261373;
    int b1 = 1261373;
    int a2 = 1669717;
    int b2 = 1293027;
    long mult1 = (long long)a1*b1; //Type cast one operand to long long
    long mult2 = (long long)a2*b2;
    printf("mult1=%ld , mult2=%ld", mult1, mult2);
}
person Ajay    schedule 13.05.2017
comment
Спасибо! В этом была проблема, я должен был разыграть его ДО умножения. Теперь это работает :) - person Juliette; 13.05.2017
comment
это решение не является переносимым: stackoverflow.com/questions/6155784/ - person niceman; 13.05.2017
comment
да, вы можете отредактировать ответ, чтобы я удалил свой отрицательный голос :) - person niceman; 13.05.2017