Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Алгоритм деления 64х разрядных чисел на 32х разрядные

Автор: taelas
Дата сообщения: 17.06.2006 12:35
Никто не подскажет такого алгоритма, чтобы работал быстро?
нужно, например, поделить dx:ax на cx...
Автор: nobody2
Дата сообщения: 19.06.2006 10:16
деление всегда медленно работает

в некоторых случаях можно использовать сдвиг (деление на степень двойки)
либо умножение (когда дробь не периодическая и не ираациональная х/5 == х*0,2)
Автор: Anatoliy_A
Дата сообщения: 19.06.2006 15:02
Вот пример из System.pas (Delphi 2006). Думаю, быстрее сделать уже не получится

* The Initial Developer of the Original Code is
* Fastcode
*
* Portions created by the Initial Developer are Copyright (C) 2002-2004
* the Initial Developer. All Rights Reserved.
*
* Contributor(s): AMD, John O'Harrow and Dennis Christensen

// ------------------------------------------------------------------------------
// 64-bit unsigned division
// ------------------------------------------------------------------------------

// Dividend(EAX(hi):EDX(lo)), Divisor([ESP+8](hi):[ESP+4](lo)) // before reg pushing
procedure __lludiv;
asm
push ebp
push ebx
push esi
push edi
//
// Now the stack looks something like this:
//
// 24[esp]: divisor (high dword)
// 20[esp]: divisor (low dword)
// 16[esp]: return EIP
// 12[esp]: previous EBP
// 8[esp]: previous EBX
// 4[esp]: previous ESI
// [esp]: previous EDI
//

// dividend is pushed last, therefore the first in the args
// divisor next.
//
mov ebx,20[esp] // get the first low word
mov ecx,24[esp] // get the first high word

or ecx,ecx
jnz @__lludiv@slow_ldiv // both high words are zero

or edx,edx
jz @__lludiv@quick_ldiv

or ebx,ebx
jz @__lludiv@quick_ldiv // if ecx:ebx == 0 force a zero divide
// we don't expect this to actually
// work

@__lludiv@slow_ldiv:
mov ebp,ecx
mov ecx,64 // shift counter
xor edi,edi // fake a 64 bit dividend
xor esi,esi

@__lludiv@xloop:
shl eax,1 // shift dividend left one bit
rcl edx,1
rcl esi,1
rcl edi,1
cmp edi,ebp // dividend larger?
jb @__lludiv@nosub
ja @__lludiv@subtract
cmp esi,ebx // maybe
jb @__lludiv@nosub

@__lludiv@subtract:
sub esi,ebx
sbb edi,ebp // subtract the divisor
inc eax // build quotient

@__lludiv@nosub:
loop @__lludiv@xloop
//
// When done with the loop the four registers values' look like:
//
// | edi | esi | edx | eax |
// | remainder | quotient |
//

@__lludiv@finish:
pop edi
pop esi
pop ebx
pop ebp
ret 8

@__lludiv@quick_ldiv:
div ebx // unsigned divide
xor edx,edx
jmp @__lludiv@finish
end;
Автор: taelas
Дата сообщения: 19.06.2006 22:45
Спасибо, но, наверное, меня не правильно поняли...
У меня задачка на 8086... там нет ничего даже отдалённо напоминающего eax :-)
Надо поделить число 64х разрядное на 32 разрядное...
Знаю, что это не всегда получается.
Я придумал только циклом последовательно вычитать...
Есть ли какое-либо более другое решение?
тут ведь примерно то-же самое...
Автор: Anatoliy_A
Дата сообщения: 20.06.2006 00:37
Если же dx:ax делить на cx, то это деление 32 разрядного числа на 16 разрядное, что реализуется с помощью одной команды и на 8086 – div cx, где

Исходные данные:
dx – старшая часть делимого
ax – младшая часть делимого
cx (регистр или память) – делитель

Результат:
ax – частное
dx – остаток
Автор: taelas
Дата сообщения: 20.06.2006 11:13
Anatoliy_A
блин. тормоз я. разряды посчитать не могу
но тем не менее,
div source
делит al, ax или eax на source. (в зависимости от размерности source) (смотрел по Зубкову)
а dx:ax не всегда будет делиться на 16-ти разрядное число
Автор: nobody2
Дата сообщения: 20.06.2006 11:56
посмотри арифметику BCD чисел.

Двоично-десятичные числа (BCD-числа).
Автор: VadimLou
Дата сообщения: 20.06.2006 14:15
В VG Library есть модуль реализующий BCD арифметику.
Автор: Anatoliy_A
Дата сообщения: 20.06.2006 16:47
taelas
а dx:ax не всегда будет делиться на 16-ти разрядное число

А можно поподробнее? Что ты имеешь ввиду под выражением "не всегда"

Страницы: 1

Предыдущая тема: Создание коммерческого софта, используя бесплатные средства


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.