|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Май 14, 2004 16:01:09 Помогите оптимизировать перевод числа в ASCII |
|
|
Дата: Май 14, 2004 16:02:41 Делаю делением получается медленно на Athlon XP Barton 8?? тактов(для полного числа) |
|
|
Дата: Май 14, 2004 16:03:33 · Поправил: Безпощадный даосConvertDWordToStr proc ;(8?? тактов) ;edi-адрес на предпоследний символ буфера ;eax-число для перевода xor edx,edx mov ebx,10 @@: div ebx add dl,'0' mov [edi],dl dec edi xor dl,dl test eax,eax jnz @B inc edi ret ConvertDWordToStr endp |
|
|
Дата: Май 14, 2004 16:38:37 · Поправил: Valery 0,8 = CCCCCCCD |
|
|
Дата: Май 15, 2004 09:46:53 [i][/i] Не понял |
|
|
Дата: Май 15, 2004 12:05:18 Посмотрите Magic Divider by The Svin здесь |
|
|
Дата: Май 15, 2004 18:45:54 Magic Divider чтука конечно полезная но мне нужен и остаток да и умноженение довольно медленное. |
|
|
Дата: Май 15, 2004 20:23:11 Довольно медленное - определение не математическое, из него трудно даже приблизительно понять, а что для тебя "хорошо". Умножение в ~4е раза быстрее деления. Остаток получаем как разность частного умноженого на 10 (умножаем 2мя однотактными командами) и прежнего числа. На PMMX было линейное ускорение до 3х раз. На современных процах по разному. А как ты иначе заменишь деление? Можно изменить на вычитание степеней десятки. Но это будет подлинней по размеру. Хотя в среднем будет чуть быстрее. Есть более быстрый метод с табличкой в 4кб для 32х битных. |
|
|
Дата: Май 15, 2004 20:48:25 · Поправил: Valery The Svin на вычитание степеней десятки Вы имеете в виду что-то типа: int div(int a, int b)
{
int positive = !(a > 0 ^ b > 0);
int result = 0;
int bm;
a = abs(a);
b = abs(b);
bm = b;
while((bm << 1) <= a)
bm <<= 1;
while(bm >= b)
{
result <<= 1;
if(a >= bm)
{
a -= bm;
result++;
}
bm >>= 1;
}
return positive ? result : -result;
}
Или нет? |
|
|
Дата: Май 15, 2004 21:42:04 Да обычное вычитание в цикле степени десятки с инкриминацией счётчика до переноса, компенсация последнего вычитания и переход к циклу с вычитанием следующей степени. Вычитаешь милльярды, сотни миллионов и т.д. Это очень примитивно выглядит и занимает много байт но работает быстро, чуть быстрее в среднем чем оптимизация деления вытеснением в старшие разряды. По крайней мере так было давным давно когда я это проверял на PMMX. |
|
|
Дата: Май 15, 2004 21:48:35 Табличку можно использовать из 16 байт (с ascii символами цифр). Так еще и избавимся от add dl,'0' Индекс в табличке получаем из бит 31..34 результата EDX:EAX : ;; edx - число mov eax,CCCCCCCDh mov ecx, 7 mul edx and ecx, edx shr edx, 3 add eax, eax rcl ecx, 1 mov al, [esi+ecx] mov [edi], al |
|
|
Дата: Май 15, 2004 22:01:52 Valery А что это ты такое написал? Я немного прибалдел. Теорию подвести можешь? |
|
|
Дата: Май 15, 2004 23:10:05 S_T_A_S_ Почему на СССССССВ? Забыл раскладку переключить. А удалил, так как после медитации понял, что все там до меня было сказано ... |
|
|
Дата: Май 15, 2004 23:12:47 · Поправил: S_T_A_S_ Black_mirror Сорри.. А то я уже сижу на калькуляторе считаю :-) imho объяснение грамотно начиналось.. |
|
|
Дата: Май 15, 2004 23:25:12
.data
align 8
dig1 = '0'
dig2 = '0'
dig3 = '0'
len = 1
tblXDec2Asc equ $
REPT 1000
dd len shl 24 + dig3 shl 16 + dig2 shl 8 + dig1
if len eq 1
dig1=dig1+1
if dig1 gt '9'
len=2
dig1='1'
endif
elseif len eq 2
dig2=dig2+1
if dig2 gt '9'
dig2='0'
dig1=dig1+1
if dig1 gt '9'
len=3
dig1='1'
endif
endif
elseif len eq 3
dig3=dig3+1
if dig3 gt '9'
dig3='0'
dig2=dig2+1
if dig2 gt '9'
dig2='0'
dig1=dig1+1
endif
endif
endif
ENDM
; edi-buffer for string
; eax-number
.code
DwordDec2Asc proc uses esi ebx lpBuffer,lpNumber
mov eax,lpNumber
mov edi,lpBuffer
mov ebx,esp
@@lpG: mov ecx,eax
mov edx,10624DD3h
mul edx
shr edx,6
imul eax,edx,1000
sub ecx,eax
mov eax,edx
push [tblXDec2Asc+4*ecx]
or eax,eax
jne @@lpG
sub ebx,esp
pop eax
mov ecx,eax
mov [edi],eax
shr ecx,24
jmp [tbl-4+ebx]
.data
align 4
tbl dd @@0,@@1,@@2,@@3
.code
@@3: pop dword ptr [edi+ecx]
add ecx,3
@@2: pop dword ptr [edi+ecx]
add ecx,3
@@1: pop dword ptr [edi+ecx]
add ecx,3
@@0: add edi,ecx
mov byte ptr [edi],0
ret
DwordDec2Asc endp
|
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.050 |