деление (компьютерное)
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:58 pm (UTC)no subject
Date: 2013-01-30 12:07 am (UTC)no subject
Date: 2013-01-30 12:29 am (UTC)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-30 12:01 am (UTC)(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2013-01-30 04:31 am (UTC)IDIV всегда делит 64-bit на 32-bit (или 32 на 16, 16 на 8)
и overflow в таком случае обычное явление. Правильный компилятор не использует IDIV напрямую, всегда вызывается функция, проверяющая делимое и делитель на допустимый диапазон.
(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2013-01-29 11:55 pm (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 02:25 pm (UTC)(no subject)
From: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 12:05 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-02-01 06:15 pm (UTC)сижу, ржу
no subject
Date: 2013-01-30 09:46 am (UTC)$ ($((-2**63/-1)))
Внешние скобки порождают дочерний баш и в нем исполняется содержимое. Это вроде логично: если команда рушит баш, то сдохнет внутренний, а внешний останется жить и нам об этом сообщит. Но дальше непонятно: двойные скобки вычисляют внутреннее выражение, а доллар исполняет результат как команду. То есть $((2+3)) — это то же самое, что исполнить команду 5, должно выдать 5: command not found. Правда, в данном примере, если баш дохнет, то до попытки запуска команды под долларом дело не доходит.
Всё же логичней запускать так:
$ ( ((-2**63/-1)) )
no subject
Date: 2013-01-30 11:34 am (UTC)no subject
Date: 2013-01-30 11:56 am (UTC)$ ((i=3+4)); echo $i
В вышеупомянутом примере доллар имел бы смысл в таком виде:
$ (echo $((-2**63/-1)))
Если туда подставить хорошее (не приводящее к ошибке) выражение, то так выводится результат выражения вместо вызова бессмысленной команды.
(no subject)
From:no subject
Date: 2013-01-30 12:52 pm (UTC)в обычном приложении, впрочем, эксепшен взлетает, факт
no subject
Date: 2013-01-30 12:54 pm (UTC)На C# то же самое
Date: 2013-01-30 07:04 pm (UTC)Интересно, а кому это надо было - делить INT_MIN/-1?