Дано: число A Найти: число B, являющееся числом A, выровненным на границу N в большую сторону. Пример: A = 7E70h, N = 200h. B = 8000h Алгоритм ((7E70 div 200h) + 1)*200h не предлагать .
_G3 Имел ввиду (A+(N-1)) AND -N наверно? Если ты просто будешь прибавлять A+N то A будет бессмысленно увеличена даже в том случае когда уже выравнена по N.
The Svin да, но Dimson уже поправил ошибка пошла от самого sword'а я от его алгоритма отталкивался и не заметил
Обычно когда встаёт вопрос о выравнивании на степень двойки то сама степень двойки предпологается как константа. Т.е. её не нужно никуда загружать. пусть в eax любое число которое нужно выравнять по 200h тогда: Код (Text): add eax,(200h-1) and eax,-200h Почему это "работает" понятно? Или требуются разъяснения?
1+1ffh=200h and -200h=200h выровнено 200h+1ffh=3ffh and -200h=200h выровнено если и теперь непонятно смотри описание команды and
Я постараюсь объяснить максимально подробно. При этом наверняка будет сказано, то что уже понятно. Поэтому не нужно говорить после "это и так понятно", так как мне пока неизвестно, что из то что "и так понятно" в данный момент непонятно Итак предметная область - округление числа в большую сторону. Задача1: Сколько нужно 10и литровых вёдер воды, чтобы разом отнести 25 литров. Ответ: 3и ведра. 2а для 20 литров, и одно оставшееся для 5и. Отметим что 25:10=2 остаток 5. Задача2: Сколько нужно 10и литровых вёдер воды, чтобы разом отнести 20 литров. Ответ: 2а ведра. Отметим что 20:10=2 остаток 0. В задаче1 могло быть не 25 литров а например любое количество x 20<x<30. И при этом ответ был бы тот же. Намеренно написано 20<x<30 а не 20<x<=30. Почему? Потому что хотелось отметить что при 20<x<30 x:10=2 и остаток не равен 0. На основании замечаний в задаче1 и в задаче2 делаем простое (но тем не менее фундаментальное для нашей задачи) замечание. Если остаток есть - мы частое увеличиваем на 1. Если нет - частное и есть наш ответ. Теперь мы изменим чуть вопрос в задаче, так чтобы проблема была максимально похожа на то, что спрашивалось в этом топике. Мы должны спросить не "сколько 10и литровых вёдер понадобится", а "какова будет суммарная ёмкость 10и литровых вёдер, которые потребуются чтобы отнести разом 25 литров воды?" И ответ будет в первом случае 30 литров, во втором 20 литров. В этом случае мы округляли число вверх до кратности 10и. Т.е. до 10<sup>1</sup> Обратим внимание, что если нам данные давали бы в десятичной системе и округлять нужно было бы до кратности степени десятки, то мы моментально смогли бы решать задачу в уме. Например разом нужно было бы отнести 1234567 литров. И вёдра были бы тоже 10и литровые. В числе 1234567 видно глядя на младший разряд какой остаток будет от деления на 10. Нам даже не важно какой именно он будет - важно ли будет он вообще или нет. Т.е. равен или нет нулю. Если он не равен нулю то часть числа старше его (123456) мы увеличиваем на 1 получая вместо него 123457 а вместо последнего разряда пишем 0. Ответ 1234570. Если бы вёдра были 100литровые (10<sup>2</sup>) мы бы могли сделать то же за исключением того что если бы увидили что в двух младших раздядах 1234567 не ноль то мы увеличили бы на 1 старшую часть числа 1234567 а нули записали бы в 2х младших разрядах. Если бы вёдра были ёмкостью 10<sup>n</sup> литров. То мы смотрели не ноль ли n младших раздядах и если нет - то увеличивали бы часть числа старших на 1 а в n младших писали бы 0. Т.е. при округлении к кратности 10<sup>n</sup> если в младших n разрядах больше нуля - увеличивается на 1 часть числа выше их а в сами n младшие разряды записывается 0. Обратим внимание что если в n младших разрядах уже 0, то вторая часть операции "записать в n младших разрядов 0" - ничего не испортит даже если число уже кратно. Важно лишь если оно уже кратно не выполнять первую часть - увеличения части старше n младших разрядов на 1. А сейчас давай зададимся вопросом А нельзя ли эту самую операцию "посмотреть в n младших разрядов и если в них не 0 увеличить на 1 часть числа старше n младших разрядов" заменить каким то простым арифметическим действием, которое если в n младших раздядах 0 НЕ увеличит часть числа выше их а если не ноль - Обязательно увеличит и обязательно на 1 какое бы отличное от ноль число там не находилось? Если мы например в задаче с 10и литровыми вёдрами прибавили к количеству воды 9? Если бы в младшем разряде был 0 то старшая часть числа бы не изменилась. Пример 120 + 9 = 129 А будь там в младшем разряде любое число x от 1 до 9 (т.е. не равное ноль мы получили бы в ответе 12x+9=13y где y было бы значение = x-1 Т.е. мы могли бы прибавить 9 к числу и после этого записать 0 в младший разряд даже не зная - делится ли оно нацело на 10 или нет - и всё равно получили бы правильный ответ. Обратим внимание что мы округляли до кратности 10<sup>1</sup> а прибавляли 9 т.е. 10<sup>1</sup> -1 А если бы вёдра были 100 литровые мы округляли бы до 10<sup>2</sup> а прибавляли бы 99 т.е. 10<sup>2</sup>-1 После чего мы сбрасывали бы 2а младших разряда в 0. Понятно что если бы вёдра были 10<sup>n</sup> литровые то прибавляли бы мы 10<sup>n</sup>-1 т.е. состоящее n 9ок. Теперь понимание обретённое в 10и чной систем переносим в двоичную. Если мы округлям двоичное число x до 2<sup>n</sup>, то также если в у числа x в n младших разрядах не 0 то часть числа выше их мы увеличиваем на 1 а в n младших разрядов пишим нули. Например x=100101 мы округлям до 2<sup>2</sup> в млаших разрядах 01 значит старшую часть числа 1001 мы увеличить должны до 1010 а в младшую записать 00 получаем 100101->101000 Опять же если мы прибавим при таком округлении к x2<sup>2</sup>-1 т.е. 3 или в бинарном виде 11 то старшая часть числа также увеличилась бы на 1, причём только тогда когда в двух младших разрядах было бы любое число кроме нуля. 100101+11=101000 ... 100111+11=101010 но 100100+11=100111 Т.е прибавив 11 к любому числу и сбросив после этого в 0 последние два биты мы получаем округлённое вверх до кратности 2<sup>2</sup> число, неважно было оно уже округлено(в этом случае число будет останется равно результату "округления") или нет. Теперь о последнем - о записи. 200h - это в бинарном виде 10 0000 0000 т.е. 2<sup>9</sup>. 200h -1 это 2<sup>9</sup> - 1. Т.е. бинарное число из 9 единиц (по аналогии с десятичной где 10<sup>9</sup> -1 было бы в десятичной записи числом из 9 девяток). Число -200h это соответсвенно -2<sup>9</sup>. And на такое число именно выполняет операцию сброса 9и младших разрядов в 0. Бинарный рисунок -1*2<sup>n</sup> таков, что в n младших разрядах у него нули а в остальных единицы. Так как x and 1 = x и x and 0 = 0 то n младших разрядов при AND на такое число сбрасываются в 0, а старшие какими были такими и остаются. Почему такой бинарный рисунок у 2<sup>n</sup> c отрицательным знаком нужно объяснять?