spamsink: (lenin)
[personal profile] spamsink
Каждый ребенок, знакомящийся с арифметической операцией деления, рано или поздно соображает: для того, чтобы получить частное от целочисленного деления числа на 10, достаточно отбросить последнюю цифру, а если она была единственной, то в ответе будет ноль. Это верно и для отрицательных чисел.

В отличие от людских голов, в компьютерах целые числа представляются без сохранения знака как отдельного признака, а в так называемом дополнительном коде: скажем, если у нас для записи целых чисел есть 8 цифр, то записать можно числа от 00000000 до 99999999. Половина из них будут представлять неотрицательные значения (от "00000000" до "49999999"), а другая половина - отрицательные (от "99999999" — что значит -1, потому что при прибавлении единицы и сохранении только 8 младших цифр получится ровно 0 — вниз до "50000000", что значит -50000000). Определять, отрицательное ли число, довольно легко: если самая левая цифра - от 5 до 9, то отрицательное. Изменение знака числа делается вычитанием из нуля: смотря справа налево, пока мы видим только нули, они остаются нулями, первая ненулевая цифра заменяется на (10 минус эта цифра), а все цифры левее нее - на (9 минус цифра).

Рассмотрим, как происходит деление на 10 в таком представлении чисел. С положительными всё просто: справа убираем цифру, слева приписываем 0, и готово. С отрицательными этот способ, с заменой приписывания слева 9 вместо 0, работает, но лишь в 10% случаев, для чисел, кратных 10: 99999990 (т.е. -10), деленное на 10, действительно будет 99999999 (т.е. -1). Но столько же получается, если делить 99999999. Мы не хотим, чтобы -1, деленное на 10, равнялось -1, мы хотим, чтобы получался ноль. Для того, чтобы метод работал правильно для всех чисел, нужна поправка: если убранная справа цифра была не 0, то после приписывания слева девятки нужно прибавить 1. Тогда, как и положено, при делении 9999999Х (где Х - от 9 вниз до 1, т.е. чисел от -1 до -9) на 10, будет 99999999+1, т.е. 0.
Казалось бы, все прекрасно. Раз мы умеем делить и положительные, и отрицательные числа на 10, то не составляет труда делить эти же числа на -10, не правда ли? Из математики мы знаем, что a/-b = -a/b, так за чем же дело стало?

Действительно, за чем же?

Date: 2016-04-23 09:49 am (UTC)
From: [identity profile] archaicos.livejournal.com
50000000/99999999?

Date: 2016-04-23 10:05 am (UTC)
From: [identity profile] ilya-dogolazky.livejournal.com
FPE, хотя казалось бы --- откуда ж тут F

Date: 2016-04-23 10:19 am (UTC)
From: [identity profile] archaicos.livejournal.com
640КБ ведь должно было хватить?

Date: 2016-04-23 10:27 am (UTC)
From: [identity profile] ilya-dogolazky.livejournal.com
а что выбрасывается на каком-нить арме например?

Date: 2016-04-23 10:56 am (UTC)
From: [identity profile] archaicos.livejournal.com
Если бросается (но не автоматически на ARM/MIPS, насколько я помню, а при помощи явной проверки), то скорее всего то же самое исключение. Я ж про что и говорю: народу было впадлу заводить отдельный сигнал в системе, типа и так сойдёт/всем хватит (ну, почти).

Date: 2016-04-24 04:43 am (UTC)
From: [identity profile] archaicos.livejournal.com
50000000/99999990 -> 50000000/00000010 -> 95000000?

Date: 2016-04-24 05:00 am (UTC)
From: [identity profile] archaicos.livejournal.com
Я когда что-то подобное делаю, то нередко для тестирования размер слова выбираю 4-8-16 бит, делаю брутфорс и сплю спокойно.

Profile

spamsink: (Default)
spamsink

February 2026

S M T W T F S
12345 67
8 91011 121314
15161718 192021
22 2324 25262728

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Mar. 5th, 2026 09:33 am
Powered by Dreamwidth Studios