Всем известен метод перевода строки в число, если на входе , предположим, десятичное "273", то это 3*(10^0) + 7*(10^1) + 2*(10^2). Т.к. в таблице ASCII числа идут по возрастанию от нуля, то достаточно вычесть 0x30 из каждого числа, чтобы получить его не в виде кода, а в виде реальной цифры. Только вот возник вопрос. Если на входе десятичное число, то можно ли, обойтись без "долгой" операции умножения. В случаи маленьких чисел - нам всё равно. В случаи целых чисел с длинной до 80бит можно подключить спороцессор. Он будет работать быстрее, чем если я сам напишу функции сложения, вычитания, умножения, деления столбиком (так ли это?) (а вот если числа будут больше 80бит, то тогда только столбиком можно). Если рассматривать случай ооочень длинных чисел, то тут всё безхитростно, я не слышал, чтобы были какие-то разные алгоритмы операций столбиком. Но рассмотрим случай с числом меньше 80бит. Это шестнадцатеричные числа с 20ю разрядами. Это же предётся умножать на 16^20, 16^19 и т.д. Как я понимаю побитовым сдвигом влево, т.е. SHL. мы получим степени 16и. А вот дальше придётся умножать разряды на эти полученные числа-степени16и.. Как это обойти?
Во-первых, в 80-битном вещественном формате (extended) мантисса составляет только 64 бита, а старшие 16 бит занимают двоичный порядок + бит знака. Поэтому точно в этом формате можно представить только 64-битные целые. Во-вторых, для умножения целых чисел на 10 используется "быстрая" комбинация lea eax,[eax+eax*4] + add eax,eax В-третьих, преобразование строки в число до 64 бит можно делать по частям: формируем первое число A до 9 десятичных знаков - запоминаем, затем формируем второе число B с подсчетом числа знаков N, затем вычисляем итог как A*10^N+B. Степень 10-ки можно взять из таблицы
MSoft А ты не знал ?! Во-всех вариациях atoi, StrToInt и т.п. юзается PS: вместо add eax,eax можно сразу и очередную цифру из edx прибавлять lea eax,[edx+eax*2]
Ничего не понял. Специально для таких случаев придуманы упакованые десятчные числа (packed decimal). Размер - 80 бит, старший бит - знаковый, младшие 72 бита - 18 десятичных цифр, по 4 бита на цифру, биты 72 - 78 не используются. Преобразуешь строку в упакованное десятичное, затем выполняешь: Код (Text): fbld tbyte ptr Packed80 fistp qword ptr Int64 и теперь в Int64 лежит готовое число.
Вообще-то достаточно уметь умножать на 10, просто переписав выражение a*(10^0) + b*(10^1) + c*(10^2) + d*(10^3)... в виде a+10*(b+10*(c+10*d)). Но и умножать не надо, как уже было отмечено коллегами. А если интересуют операции с о-о-о-очень длинными цифрами, советую глянуть http://pari.math.u-bordeaux.fr/ Там и исходники есть.
а если динамика? для каждого разряда составить таблицу со значениями, вычисление индекса сдвигом - а дальше только сложение. возможно конечно от такой идеи толку ноль, надо прикидывать что получится...
и как ты себе это представляешь. первый разряд 00001111b = 1|2|3|4|5|6|7|8|9 второй разряд 01111110b = 10|20|30|40|50|60|70|80|90 третий разряд ... ну из-за того что 10=2*2*2+2 ничего не получится (вот убери лишнюю 2 и все прекрасно)
ava Не думаю, что они были придуманы "специально для этого" Одно только преобразование строки к формату BCD, займет не меньше времени, чем непосредственной формирование пары чисел с использованием быстрого умножения на lea. Плюс команда fbld на современных компах отнюдь не быстрая - от 40-45 тактов на P6 и атлонах до 80-90 тактов на P4. Плюс возможный штраф, сравнимый с длиной конвеера, на чтение целого после частичной записи (STLF restriction), плюс опасность реплэя на первых моделях P4
Может как-нибудь так Код (Text): org 100h movaps xmm0,dqword[s] psubusb xmm0,dqword[a] pmaddubsw xmm0,dqword[b] pmaddwd xmm0,dqword[c] pmullw xmm0,dqword[d] phaddd xmm0,xmm0 phaddd xmm0,xmm0 movd eax,xmm0 cmp eax,123 @@:je @b ret align 16 s db '123',0 rb 16 a db 48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48 b db 1,10,1,10,1,10,1,10,1,10,1,10,1,10,1,10 c dw 1,100,1,100,1,100,1,100 d dd 1,10000,100000000,0 P.S. код не проверял т.к. нету SSE3