vak: (Default)
[personal profile] vak
Сложить два целых числа, вернуть целое. Породить исключение в случае арифметического переполнения.
int add(int a, int b);
Удивительно, сколько народу обламывается на этой задачке.

Date: 2020-08-02 13:45 (UTC)
waqur: (Default)
From: [personal profile] waqur
Вспомнил про флаг OF в интеловской архитектуре x86 и полез в Википедию читать правила его вычисления:

Internally, the overflow flag is usually generated by an exclusive or of the internal carry into and out of the sign bit.

Мило, но вряд-ли аппликант на работу додумается до этого на собеседовании, если не знает заранее.

Carry out of the sign bit можно вычислить, как я уже говорил, после кастинга обоих операндов к unsigned int, их сложения, и сравнения суммы с любым из них, например первым. Если сумма беззнаковых меньше первого беззнакового — значит бит Carry out равен 1, иначе 0.

Carry in можно вычислить, просто применив AND-маску ((unsigned int)(INT_MAX)) к обоим операндам в беззнаковой форме перед сложением. Нужный нам бит "Carry in of the sign bit" будет в старшем бите результата после сложения.

А далее просто XOR этих carry in и carry out, как учит Википедия. :)

Интересно, найдётся ли компилятор, который преобразует все эти извращения обратно в инструкцию чтения флага OF.