PDA

Просмотр полной версии : Расчет модуля разности чисел



Andrew771
24.08.2012, 09:55
Дано: в регистрах A и B любые числа.
Найти: A=|A-B|

Нужен самый быстрый и короткий алгоритм.

Vitamin
24.08.2012, 10:18
sub b
jr nc,$+3
neg

moroz1999
24.08.2012, 10:40
neg? omg, я и не знал, что такой есть.

Alex Rider
24.08.2012, 13:01
Код:


sub b
jr nc,$+3
neg



neg = #ed44, куда будет переход на $+3? ;)

Vitamin
24.08.2012, 13:21
neg = #ed44, куда будет переход на $+3?
Ашыпся:) Надо меньше умничать:



sub b
jr nc,positive
neg
positive:

Andrew771
24.08.2012, 15:57
Пасибо большое, Vitamin, а то я лепил перестановку регистров A и B :)

goblinish
24.08.2012, 19:02
интересно, а если числа отрицательные, то прокатит ли?
например, $FF=-1, $FE=-2

SfS
24.08.2012, 19:33
интересно, а если числа отрицательные, то прокатит ли?
например, $FF=-1, $FE=-2

FF - FE = 1 (-2 - -1 = 1) переноса нет. всё верно.
FE - FF = -1 (-2 - -1 = -1) перенос есть, neg FF = 1

Всё прокатит)

Andrew771
29.08.2012, 17:26
Ну в реальности я использую для измерения расстояний между координатами юнитов/полей, так что достаточно положительных и нуля. :)

Barmaley_m
29.08.2012, 18:59
Для измерения расстояний в какой геометрии? Не на плоскости ли? Может лучше применять теорему Пифагора и вычислять квадрат разности, а не ее модуль?

goblinish
29.08.2012, 19:18
Для измерения расстояний в какой геометрии? Не на плоскости ли? Может лучше применять теорему Пифагора и вычислять квадрат разности, а не ее модуль?
ага, заодно и алгоритм sqr приписать

SfS
29.08.2012, 20:00
Для измерения расстояний в какой геометрии? Не на плоскости ли? Может лучше применять теорему Пифагора и вычислять квадрат разности, а не ее модуль?

Я, конечно, строю догадки, но:

1. В игре возможно нужно не само расстояние, а только "дальше-ближе".

2. Очевидно, что
SQRT(X0^2+Y0^2) > SQRT(X1^2+Y1^2) => (abs(X0)+abs(y0)) > (abs(X1)+abs(y1))

по крайней мере для целых чисел (координаты не дробные ведь).

3. Исходя из (2) для получения (1) достаточно иметь abs(), что и хочет автор топика.

Я не прав?

Barmaley_m
29.08.2012, 20:22
Я не прав?
Не прав. Привожу контрпример. Если x0=1, y0=5, x1=3, y1=4, то имеем:

sqrt(x0^2+y0^2) = sqrt(1+25) = sqrt(26)~=5.099
sqrt(x1^2+y1^2) = sqrt(9+16) = sqrt(25)=5
следовательно sqrt(x0^2+y0^2) > sqrt(x1^2+y1^2)
однако при этом
abs(x0)+abs(y0) = 1+5=6
abs(x1)+abs(y1) = 3+4=7
следовательно abs(x0)+abs(y0) < abs(x1)+abs(y1)

На самом деле, работая с расстояниями, часто можно обойтись без операции извлечения квадратного корня. Достаточно иметь операцию возведения в квадрат. Потому что если sqrt(x0^2+y0^2)>sqrt(x1^2+y1^2) - то x0^2+y0^2 > x1^2+y1^2. Если расстояние, к тому же, сравнивается с константой - то ее квадрат можно вычислить заранее один раз.

Квадраты вычислять легко с помощью таблицы квадратов, если исходные числа 8-битные. Таблица занимает в этом случае всего 512 байт памяти.

---------- Post added at 18:22 ---------- Previous post was at 18:14 ----------

В некоторых случаях работа с квадратами еще более упрощается, если вычисляются квадраты последовательных целых чисел, потому что:
(x+1)^2 = x^2 + 2*x + 1
То есть квадрат следующего числа равен квадрату предыдущего плюс единица плюс удвоенное предыдущее число. Это тождество используется в алгоритме Брезенхама рисования окружности.

SfS
29.08.2012, 20:41
Достаточно иметь операцию возведения в квадрат. Потому что если sqrt(x0^2+y0^2)>sqrt(x1^2+y1^2) - то x0^2+y0^2 > x1^2+y1^2. Если расстояние, к тому же, сравнивается с константой - то ее квадрат можно вычислить заранее один раз.




Точно! Я помню что раньше как-то без корня обходились! Про возведение в квадрат я не подумал)) Прошу прощения.

Andrew771
30.08.2012, 12:48
Я, конечно, строю догадки, но:

1. В игре возможно нужно не само расстояние, а только "дальше-ближе".

2. Очевидно, что
SQRT(X0^2+Y0^2) > SQRT(X1^2+Y1^2) => (abs(X0)+abs(y0)) > (abs(X1)+abs(y1))

по крайней мере для целых чисел (координаты не дробные ведь).

3. Исходя из (2) для получения (1) достаточно иметь abs(), что и хочет автор топика.

Я не прав?
Прав. Я так и делаю в нынешней пошаговой стратегии. Особая точность там не нужна. Главное, определить, попадает ли объект в обработку к юниту или нет.

Screw
15.02.2013, 21:06
neg? omg, я и не знал, что такой есть.

А если бы и не было ?
CPL : INC A

Абсолютно тоже самое, и по размеру (2 байта) и по времени исполнения (8 тактов). Все отличие во флаге переноса, который устанавливает NEG, но не трогает CPL/INC A.