Ответ на задачку по Си
2020-08-03 12:14Исчерпывающий ответ на задачу сложить два числа дал
spamsink : https://vak.dreamwidth.org/659406.html?thread=5230798#cmt5230798
Вот код на Си++, решающий поставленную задачу, не вызывая неопределённого поведения и не прибегая к трюкам.
Вот по этой причине физики не любят Си и Си++. Вы даже два числа сложить не можете без фокусов, говорят они. :)
Заметим, что проблема undefined behavior в арифметике свойственна только Си/Си++. Во многих современных языках, таких как Java, Go или Rust, она отсутствует.
Вот код на Си++, решающий поставленную задачу, не вызывая неопределённого поведения и не прибегая к трюкам.
Как видите, вовсе не теорема Ферма. Not a rocket science, как говорят американцы. Последовательность простых логических рассуждений.int add(int a, int b)
{
int sum;
if (a >= 0) {
if (b >= 0) {
// Оба числа положительные - сместим на верхнюю границу.
sum = (a - INT_MAX) + b;
if (sum > 0)
throw std::overflow_error("Integer overflow");
sum += INT_MAX;
} else {
// Разные знаки, нет переполнения.
sum = a + b;
}
} else {
if (b >= 0) {
// Разные знаки, нет переполнения.
sum = a + b;
} else {
// Оба числа отрицательные - сместим на нижнюю границу.
sum = (a - INT_MIN) + b;
if (sum < 0)
throw std::overflow_error("Integer overflow"); sum += INT_MIN;
}
}
return sum;
}
Вот по этой причине физики не любят Си и Си++. Вы даже два числа сложить не можете без фокусов, говорят они. :)
Заметим, что проблема undefined behavior в арифметике свойственна только Си/Си++. Во многих современных языках, таких как Java, Go или Rust, она отсутствует.

no subject
Date: 2020-08-03 21:21 (UTC)Допустим a и b уже >= 0.
Условие переполнения a + b очевидное: a + b > INT_MAX.
Но в C его так в лоб записать нельзя, т.к. это переполнение возникнет в проверке.
Но можно написать if (a > INT_MAX - b) или if (b > INT_MAX - a), и переполнения не возникнет.
Тут можно было бы и остановиться. Но можно переписать в форме
if ((a - INT_MAX) + b > 0) или if ((b - INT_MAX) + a > 0).
И тоже не будет переполнения.
no subject
Date: 2020-08-03 21:34 (UTC)a+b > INT_MAX в си можно написать как a+b < 0.
no subject
Date: 2020-08-03 21:43 (UTC)no subject
Date: 2020-08-03 21:47 (UTC)Ах вон как. Ну тогда ладно, тогда шифт - единственное решение.