Все кто программировал на си, наверное, знакомы с таким понятием как сигналы, это один из механизмов IPC в POSIX совместимых операционных системах.
В данном случае речь пойдет конкретно об ошибках при вычислениях с плавающей точкой.
Для примера реализуем простую программу обрабатывающую SIGFPE :
Это демонстрационный пример и дабы не загромождать код, упустим некоторые проверки.
Начнем с вещей очевидных, что будет если передать вторым параметром 0 ?
Теперь перейдем к чему-то более интересному и не всем известному.
Вот такой пример :
Интересный факт о функции abs(int) :
В данном случае речь пойдет конкретно об ошибках при вычислениях с плавающей точкой.
Для примера реализуем простую программу обрабатывающую SIGFPE :
Это демонстрационный пример и дабы не загромождать код, упустим некоторые проверки.
Начнем с вещей очевидных, что будет если передать вторым параметром 0 ?
bash -> ./sigfpe 1 0
SIGFPE catched!
Думаю всем понятно, почему все пошло именно по такому пути развития.Теперь перейдем к чему-то более интересному и не всем известному.
Вот такой пример :
bash -> ./sigfpe -2147483648 -1
SIGFPE catched!
Почему произошло исключение? Давай-те взглянем, как представлено число -2147483648, данное число является минимальным отрицательным, которое можно представить в 32-х разрядном регистре.-2147483648 -> 0x80000000 -> 1000 0000 0000 0000 0000 0000 0000 0000
Теперь о том, как происходит смена знака. Смена знака происходит инвертированием всех битов числа и добавления к получившемуся значению единицы. Это справедливо почти для всех чисел, кроме 0 и -2147483648
0x80000000 -> 1000 0000 0000 0000 0000 0000 0000 0000
NOT(0x80000000) -> 0111 1111 1111 1111 1111 1111 1111 1111
ADD(1) -> 1000 0000 0000 0000 0000 0000 0000 0000
0x00000000 -> 0000 0000 0000 0000 0000 0000 0000 0000
NOT (0) -> FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF
ADD (1) -> 0000 0000 0000 0000 0000 0000 0000 0000
Таким образом, число 2147483648 невозможно представить в 32-х разрядном регистре.Интересный факт о функции abs(int) :
/* Return the absolute value of I. */
int
abs (int i)
{
return i < 0 ? -i : i;
}
Как уже была сказано, -INT_MIN = INT_MIN.
Комментариев нет:
Отправить комментарий