Автор: xen. Дата публикации: 10.08.2004
Процедура Rsin$ вычисляет тригонометрическую функцию sin от 32-битного аргумента. 32-битная система с фиксированной точкой определяется следующим образом:
;значение переменной F32bit = 4.750
F32bit dw 49152 ;дробная часть (0.75*65536)
dw 4 ;целая часть
Использование процедуры:
Входные данные: смещение аргумента в BX, смещение результата в AX. Аргумент задает угол в градусах.
Выходные данные: значение функции sin, записываемое в переменную, смещение которой определяется регистром AX. Значения регистров не сохраняются.
Например, sin(30.5°) вычисляется так:
В результате такого вызова вы получите результат 0.50752 в то время как правильное значени еравно 0.50754
Функция синуса в 32-битной системе с фиксированной точкой
Процедура Rsin$ вычисляет тригонометрическую функцию sin от 32-битного аргумента. 32-битная система с фиксированной точкой определяется следующим образом:
;значение переменной F32bit = 4.750
F32bit dw 49152 ;дробная часть (0.75*65536)
dw 4 ;целая часть
Использование процедуры:
Входные данные: смещение аргумента в BX, смещение результата в AX. Аргумент задает угол в градусах.
Выходные данные: значение функции sin, записываемое в переменную, смещение которой определяется регистром AX. Значения регистров не сохраняются.
Например, sin(30.5°) вычисляется так:
Angle dd 001E8000h ;старший байт=30, младший байт=32768
Result dd ? ;сюда будет записан результат
....
mov AX,offset Result
mov BX,offset Angle
call Rsin$
В результате такого вызова вы получите результат 0.50752 в то время как правильное значени еравно 0.50754
Rsin$ proc
; значение синуса аргумента (двойное слово по смещению BX) вычисленное как двойное слово по смещению AX.
; Угол (по смещению BX) в градусах в диапазоне -360...360.
push AX ;сохраняем смещение результата
mov AX,[BX+2] ;целая часть угла
mov CX,[BX] ;дробная часть угла
mov DX,1 ;знак результата - +1 или -1
or AX,AX ;какой знак?
jns Rsin_1
not AX ;меняем знак
not CX
add CX,1
adc AX,0
neg DX ;также меняется знак результата
Rsin_1: ;теперь имеем угол в диапазоне 0...360
; уменьшаем диапазон до 0...180
cmp AX,180 ;угол больше 180?
jl Rsin_2
sub AX,180
neg DX ;изменяем знак результата
Rsin_2: ;теперь угол AX:CX в диапазоне 0...179.99998
cmp AX,90 ;угол больше 90?
jl Rsin_3
mov BX,180 ;вычисляем 180-угол
sub SI,SI
sub SI,CX
sbb BX,AX
mov AX,BX
mov CX,SI
Rsin_3: ;угол в AX:CX в диапазоне 0...90
push DX ;сохраняем знак результата в стеке
cmp AX,90 ;угол равен 90?
jne R_sin4
mov AX,1 ;возвращаем 1.0000
sub BX,BX
jmp short Rsin_9
R_sin4:
mov SI,offset Rsin_t ;таблица значений синусов
add SI,AX
add SI,AX
sub AX,AX ;целая часть значения синуса
mov BX,[SI] ;дробная часть
or CX,CX ;дробная чать равна 0?
jz Rsin_9
; интерполяция между значениями [SI] и [SI+2]
mov AX,[SI+2]
sub AX,BX ;AX = sin(a+1)-sin(a)
mul CX ;CX=0... 0.9999, результат DX= AX*CX/65536
add BX,DX ;добавим получившийся результат к значению из таблицы
sub AX,AX ;целая часть результата
Rsin_9:
pop DX ;корректируем знак результата AX:BX
or DX,DX
jns Rsin_loppu
not AX ;изменяем знак результата
not BX
add BX,1
adc AX,0
Rsin_loppu:
pop DI ;смещение результата
mov [DI+2],AX ;записываем целую часть
mov [DI],BX ;дробная часть
ret
Rsin$ endp
;таблица синусов
Rsin_t dw 0,1144,2287, 3430, 4572, 5712, 6850, 7987, 9121,10252
dw 11380,12505,13626,14742,15855,16962,18064,19161,20252,21336
dw 22415,23486,24550,25607,26656,27697,28729,29753,30767,31772
dw 32768,33754,34729,35693,36647,37590,38521,39441,40348,41243
dw 42126,42995,43852,44695,45525,46341,47143,47930,48703,49461
dw 50203,50931,51643,52339,53020,53684,54332,54963,55578,56175
dw 56756,57319,57865,58393,58903,59396,59870,60326,60764,61183
dw 61584,61965,62328,62672,62997,63303,63589,63856,64104,64332
dw 64540,64729,64898,65048,65177,65287,65376,65446,65496,65526
dw 0 ;для интерполяции
Комментарии |
отсутствуют |
Добавление комментария |