vak: (Default)
[personal profile] vak
Исчерпывающий ответ на задачу сложить два числа дал [personal profile] spamsink : https://vak.dreamwidth.org/659406.html?thread=5230798#cmt5230798

Вот код на Си++, решающий поставленную задачу, не вызывая неопределённого поведения и не прибегая к трюкам.
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;
}
Как видите, вовсе не теорема Ферма. Not a rocket science, как говорят американцы. Последовательность простых логических рассуждений.

Вот по этой причине физики не любят Си и Си++. Вы даже два числа сложить не можете без фокусов, говорят они. :)

Заметим, что проблема undefined behavior в арифметике свойственна только Си/Си++. Во многих современных языках, таких как Java, Go или Rust, она отсутствует.

Date: 2020-08-03 22:08 (UTC)
spamsink: (Default)
From: [personal profile] spamsink
Это у тебя взгляд узкий, поэтому ты и думаешь, что всегда. Вон, я в VHDL объявлю какой-нибудь целый тип как integer range (-3 to 4), и синтезатор будет в полном праве отвести под него всего 3 бита.

Date: 2020-08-03 22:33 (UTC)
archaicos: Шарж (Default)
From: [personal profile] archaicos
Вопрос же по C/C++, а там три возможных варианта для представления целых чисел со знаком. Два симметричны: -INT_MAX==INT_MIN. А один нет: -INT_MAX==INT_MIN+1. И именно этот один наиболее представлен в природе сегодня.
А так-то, можно изобрести чо угодно. И без VHDL.

Date: 2020-08-04 01:33 (UTC)
spamsink: (Default)
From: [personal profile] spamsink
Я давал максимально общий ответ, не привязанный к языкам программирования и представлению чисел.