деление (компьютерное)
Jan. 30th, 2013 01:18 amПрикольно - оказывается, инструкция idiv, деление со знаком, на x86 кидает исключение не только при делении на ноль, но и когда результат не помещается в регистр. А этого очень легко добиться, написав в C например INT_MIN / -1. Как мы помним, INT_MIN по модулю на единицу больше, чем INT_MAX; например, в 32-битных числах INT_MIN равно -2147483648, а INT_MAX равно 2147483647. Поэтому когда INT_MIN делят на -1, положительный результат не вмещается в 32 бита.
Само по себе это не катастрофа - ну кидает исключение, ну и подумаешь. Дело в том, однако, что про деление на ноль все знают и помнят, и проверяют перед попыткой делить. А против INT_MIN/-1 никто практически не защищается. Поэтому можно, например:
- крэшнуть компилятор (правда, игрушечный), PostgreSQL (не игрушечную) или антивирус;
- подвесить Windows 8;
- убить bash
Само по себе это не катастрофа - ну кидает исключение, ну и подумаешь. Дело в том, однако, что про деление на ноль все знают и помнят, и проверяют перед попыткой делить. А против INT_MIN/-1 никто практически не защищается. Поэтому можно, например:
- крэшнуть компилятор (правда, игрушечный), PostgreSQL (не игрушечную) или антивирус;
- подвесить Windows 8;
- убить bash
no subject
Date: 2013-01-29 11:24 pm (UTC)no subject
Date: 2013-01-29 11:39 pm (UTC)idiv берет два параметра когда первый параметр имеет в два раза больше битов чем второй, так что даже деление на два, при неправильных параметрах выдаст overflow
http://pdos.csail.mit.edu/6.828/2011/readings/i386/IDIV.htm
no subject
Date: 2013-01-29 11:42 pm (UTC)no subject
Date: 2013-01-29 11:45 pm (UTC)no subject
Date: 2013-01-29 11:49 pm (UTC)no subject
Date: 2013-01-29 11:55 pm (UTC)Доктор, что я делаю не так? :-)
no subject
Date: 2013-01-29 11:58 pm (UTC)no subject
Date: 2013-01-30 12:01 am (UTC)no subject
Date: 2013-01-30 12:05 am (UTC)no subject
Date: 2013-01-30 12:07 am (UTC)no subject
Date: 2013-01-30 12:08 am (UTC)no subject
Date: 2013-01-30 12:09 am (UTC)no subject
Date: 2013-01-30 12:09 am (UTC)no subject
Date: 2013-01-30 12:16 am (UTC)// Product: WinNt, suite: TerminalServer SingleUserTS
// Built by: 9200.16384.x86fre.win8_rtm.120725-1247
no subject
Date: 2013-01-30 12:23 am (UTC)Бардак везде.
no subject
Date: 2013-01-30 12:29 am (UTC)no subject
Date: 2013-01-30 12:38 am (UTC)no subject
Date: 2013-01-30 01:00 am (UTC)no subject
Date: 2013-01-30 01:07 am (UTC)no subject
Date: 2013-01-30 01:12 am (UTC)no subject
Date: 2013-01-30 01:34 am (UTC)Если есть нормативный документ, требующий перепрыгивающего поведения, имеем ошибку реализации, которую можно донести реализаторам, чтобы те её исправили.
Если это всё чепуха, тогда имеет смысл надавить на документаторов, чтобы они чётче определили поведение в данной ситуации.
Кстати, на странице по последней ссылке вообще написано следующее: Integer division by zero has undefined result. On some architectures it will generate a SIGFPE signal. (Also dividing the most negative integer by -1 may generate SIGFPE.) Ignoring this signal might lead to an endless loop.
Сейчас это можно практически трактовать только как то, что искомое поведение не является гарантированным на практике.
no subject
Date: 2013-01-30 02:14 am (UTC)Floating point exception: 8
bolk@Bolk /$ bash --version
GNU bash, version 4.2.42(2)-release (i386-apple-darwin12.2.0)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
no subject
Date: 2013-01-30 03:09 am (UTC)no subject
Date: 2013-01-30 04:31 am (UTC)IDIV всегда делит 64-bit на 32-bit (или 32 на 16, 16 на 8)
и overflow в таком случае обычное явление. Правильный компилятор не использует IDIV напрямую, всегда вызывается функция, проверяющая делимое и делитель на допустимый диапазон.
no subject
Date: 2013-01-30 05:27 am (UTC)