(C) Maximum/INTEGER
LONG ??? Что это такое ?
─────────────────────────────
Так обозначаются длинные числа на
PC и на AMIGA . Т. е это числа, лежащие в
диапазоне от 0 до 4294967295, для предс-
тавления которых отводится 4 (четыре)
байта в памяти.
В данной статье я научу вас опери-
ровать с такими числами. И для чего это
надо? например, вы пишете игру, в которой
есть такие параметры,как деньги, золото и
т. д. Как водится, денег в таких играх
бывает намного больше, чем 65535. Вот
здесь-то как раз и пригодятся LONG цифер-
ки...
Итак, у нас есть число 12. 000. 00.
В Long оно выглядит так: #00B71B00
В ассемблере же стоит набирать так:
long_num DW #00B7, #1B00
Формат задания любого Long числа:
...
LD HL,#00B7
EXX
LD HL,#1B00
...
Т.е в HL старшая часть числа, а в
HL' его младшая часть.
Сложение двух Long чисел
────────────────────────────
Надо просто сложить младшие части,
а потом с учетом флага C сложить и стар-
шие:
L_ADD
ADD HL,DE
EXX
ADC HL,DE
EXX
RET
На входе у процедуры: HL и HL' -
первое число, в DE и DE' - второе число.
На выходе: HL и HL' сумма двух чи-
сел.
Разность двух Long чисел
────────────────────────────
Здесь примерно то же самое:
L_SUB
AND A
SBC HL,DE
EXX
SBC HL,DE
RET
Параметры такие же, как у L_ADD.
Печать Long чисел
─────────────────────
Для печати числа нам нужно его пе-
рекодировать из Long в ASCII коды, что и
делает следующая процедура:
L_PR LD IX,L_TAB; см.ниже
LD A,10 ; число из 10 знаков
L_PR0 EX AF,AF'
EXX
LD E,(IX+0); ст.слово из табл.
LD D,(IX+1)
EXX
LD E,(IX+2); мл.слово из табл.
LD D,(IX+3)
LD A,'0'-1
L_PR1 CALL L_SUB ; отнимаем пока не
INC A ; включится флаг C
JR NC,L_PR1;
CALL L_ADD ; востановим число
LD (BC),A ; в буфер его
INC BC
INC IX
INC IX
INC IX
INC IX
EX AF,AF'
DEC A
JR NZ,L_PR0; все числа
RET ; ...
;таблица чисел:
L_TAB DW #3B9A,#CA00 ; 1000000000
DW #05F5,#E100 ; 100000000
DW #0098,#9680 ; 10000000
DW #000F,#4240 ; 1000000
DW #0001,#86A0 ; 100000
DW #0000,#2710 ; 10000
DW #0000,#03E8 ; 1000
DW #0000,#0064 ; 100
DW #0000,#000A ; 10
DW #0000,#0001 ; 1
Перед вызовом в HL и HL' число, а в
BC адрес буфера для числа. Пример:
ORG #6000
LD HL,#FFFF
EXX
LD HL,#FFFF
LD BC,BUFF
CALL L_PR
CALL 3435
LD A,2
CALL 5633
LD HL,BUFF
LD B,10
LOOP LD A,(HL)
RST 16
INC HL
DJNZ LOOP
RET
BUFF DS 10
Ввод Long числа.
───────────────────
Вернее не ввод, а преобразование числа
из ASCII кодов в Long формат. Применить
это можно так:
...
LD HL,BUFF
...
CALL INPUT ;Вводим число
LD HL,BUFF
CALL L_DC
...
На входе у процедуры: HL-адрес буфера,
где сидит число:
BUFF DB "212042067"
DB 0 ;Маркер конца т.е
;код <"0" и >"9"
После вызова в HL и HL' будет число.
L_DC PUSH HL
LD B,0
L_DC1 LD A,(HL) ;Подсчитаем сколько
CP "0" ;циферок у нашего
JR C,L_DC2 ;числа
CP "9"+1
JR NC,L_DC2
INC B
INC HL
JR L_DC1
L_DC2 EXX
POP BC ;в BC его
LD HL,0 ;Обнулим
EXX ;новое
LD HL,0 ;число
EXX
L_DC3 LD A,B ;все зделали ?
LD DE,0-4
AND A
RET Z ;нееет !
EXX
DEC A ;используя таблицу
LD IX,L_TAB+36
JR Z,L_DC4 ;найдем
ADD IX,DE ;нужный
DEC A ;нам
JR Z,L_DC4 ;разряд
ADD IX,DE ;числа
DEC A
JR Z,L_DC4
ADD IX,DE
DEC A
JR Z,L_DC4
ADD IX,DE
DEC A
JR Z,L_DC4
ADD IX,DE
DEC A
JR Z,L_DC4
ADD IX,DE
DEC A
JR Z,L_DC4
ADD IX,DE
DEC A
JR Z,L_DC4
ADD IX,DE
DEC A
JR Z,L_DC4
ADD IX,DE
L_DC4 DEC B ;ага, нашли
LD E,(IX) ;берем то что
LD D,(IX+1) ;мы будем
EXX ;прибавлять
LD E,(IX+2) ;к
LD D,(IX+3) ;новому числу
LD A,(BC) ;какое у вас число ?
INC BC
L_DC5 CP "0" ;пока не "ноль"
JR Z,L_DC3
CALL L_ADD ;прибавляем разряд
DEC A
JR L_DC5
Ну все, я дал уже достаточно много
информации про Long, так что пользуйтесь
на здоровье...
Надеюсь, что данная статья кому-то
поможет. Еще хочу напомнить, что такими
числами уже успешно воспользовался всем
известный Слава Медноногов в своей UFO.
Больше я такого метода пока нигде не
встречал.
* * *