Отрицательные двоичные числа

Тема в разделе "WASM.BEGINNERS", создана пользователем Nikankin, 28 янв 2008.

  1. Nikankin

    Nikankin New Member

    Публикаций:
    0
    Регистрация:
    17 янв 2008
    Сообщения:
    16
    По Питеру Абелю...

    Отрицательные числа
    ---------------------
    Все представленные выше двоичные числа имеют положительные значения,
    что обозначается нулевым значением самого левого (старшего) разряда.
    Отрицательные двоичные числа содержат единичный бит в старшем разряде и
    выражаются двоичным дополнением. Т.е., для представления отрицательного
    двоичного числа необходимо инвертировать все биты и прибавить 1.
    Рассмотрим пример:

    Число 65: 01000001
    Инверсия: 10111110
    Плюс 1: 10111111 (равно -65)

    А разве 10111111 не равно -63? Или я не до конца допонял. Подскажите пожалуйста
     
  2. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    ~10111111 + 1 = 01000000 + 1 = 01000001
     
  3. Qasm

    Qasm New Member

    Публикаций:
    0
    Регистрация:
    9 янв 2008
    Сообщения:
    14
    У меня проблема по отрицательным числам. Как их вообще сравнивать?

    Подробности:
    Обрабатываю WM_MOUSEMOVE. Я вызывал SetCapture, поэтому движения мыши будут передаваться окну даже если мышь не над окном. Извлекаю из lParam координаты. Потом вызываю GetClientRect. Мне нужно ловить следующие моменты:так:
    - когда мышь находится вне окна и справа
    - когда мышь находится вне окна и слева

    Если мышь находится слева от окна (вне окна), то координата Х принимает отрицательное значение. Но узнать, меньше он нуля или нет, не получается. Писал примерно так:
    Код (Text):
    1. .if XPos < 0
    2.   ; ...
    3. .endif
    но это не действует, так как если дать XPos функции wvsprintf, то он вернет где то около 65535. Я так думаю, что .if работает с числами как с положительными, то есть XPos он воспринимает не как -20, а как, допустим, 65340. Как исправить? Пожалуйста помогите, я на этом на два дня застрял.
     
  4. Nikankin

    Nikankin New Member

    Публикаций:
    0
    Регистрация:
    17 янв 2008
    Сообщения:
    16
    rei3er? но ведь если сложить положительное число и отрицательно (обратное +1) будет ноль, т.е. 10111111 должно быть -65, а иначе ноль как получится?
     
  5. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Nikankin
    10111111 (-65)
    +
    01000001 (65)
    =
    00000000

    В чем вопрос-то?

    Кстати, дополнение работает не только для двоичных чисел, но и для любой системы счисления. Поэтому, если в двоичной непривычно, можно потренироваться в десятичной.
     
  6. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.347
    Qasm
    cmp
    jl
     
  7. nobodyzzz

    nobodyzzz New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2005
    Сообщения:
    475
    Ноль получится в результате того что результат сложение этих чисел не влезет в разрядную сетку
    0100 0001
    + 1011 1111
    ------------
    1 0000 0000
     
  8. Qasm

    Qasm New Member

    Публикаций:
    0
    Регистрация:
    9 янв 2008
    Сообщения:
    14
    Не получается... Он их воспринимает как положительные числа. Он сравнивает 6553* с нулем, а мне нужно чтоб он сравнивал отрицательное число с нулем.
     
  9. Nikankin

    Nikankin New Member

    Публикаций:
    0
    Регистрация:
    17 янв 2008
    Сообщения:
    16
    Mika0x65, а вопрос в том, что 10111111 не равен -65, а равен -63, а -63 + 65 не будет нулем
     
  10. T800

    T800 Member

    Публикаций:
    0
    Регистрация:
    7 дек 2006
    Сообщения:
    293
    Адрес:
    Moscow
    Qasm
    Кто воспринимает то? Компилятор?
    signed или не signed XPos определяется лишь тем, при помощи каких команд ты с XPos работаешь.
     
  11. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Nikankin
    Ну ведь уже показали, как получается отрицательное число:

    01000001(65) = ~(01000001) + 1 = 10111110 + 1 = 10111111(-65).

    И наоборот:

    10111111(-65) = ~(10111111) + 1 = 01000000 + 1 = 01000001(65).

    ~ означает побитовое отрицание.
     
  12. Nikankin

    Nikankin New Member

    Публикаций:
    0
    Регистрация:
    17 янв 2008
    Сообщения:
    16
    Пардон ребята, как же я упустил, ведь в двоичных отрицательных величина числа выражается значениями нулевых битов, в отличие от положительных.
    А я дурень, уже калькулятором воспользовался, сижу единичные биты считаю :)
     
  13. Qasm

    Qasm New Member

    Публикаций:
    0
    Регистрация:
    9 янв 2008
    Сообщения:
    14
    Работаю как обычно, mov add sub mul div cmp jl и т.д.
    XPos извлекаю из lParama. Когда сравнивает число 30 и 0, он (тот, кто выполняет код) думает, что 30 больше чем 0. А если начнет сравнивать 30 и -20, он будет думать, что -20 > 30. Какие операторы сравнения использовать нужно?
     
  14. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Нет, 10111111 - это -65
    -63 = 11000001

    Как уже написали
    Т.е. код:

    Код (Text):
    1. test al,al
    2. js    @signed_negative     ; здесь идёт переход если число <0, можно jl написать
    Код (Text):
    1. test al,al
    2. jb    @signed_negative     ; а здесь никогда переход не сработает, jb для беззнаковых чисел, и меньше нуля они быть не могут
    Т.е. jl/jg (less/greater) - это для чисел со знаком, jb/ja (below/abow) - для беззнаковых.
    Само число может расцениваться как знаковое, так и беззнаковое - всё зависит от команд при помощи которых ты с ним работаеш:
    10111111 = -65 = 191
     
  15. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Показывай свой код

    Код (Text):
    1. mov al,-20
    2. cmp al,30
    3. jl  @smaller     ; тут переход происходит
    4. nop
    5. @smaller:
    6. nop
     
  16. Qasm

    Qasm New Member

    Публикаций:
    0
    Регистрация:
    9 янв 2008
    Сообщения:
    14
    Код (Text):
    1. ; ---------- извлечение XPos ----------
    2.         mov     eax,lParam
    3.         shr     eax,16
    4.         mov     YPos,eax
    5.         mov     eax,lParam
    6.         and     eax,0FFFFh
    7.         mov     XPos,eax
    8. ; ---------- Проблемный момент ----------
    9.         mov     eax,0
    10.         cmp     XPos,eax
    11.         jl      qwerty1
    12.         jmp     qwerty2
    13.         qwerty1:
    14.             ; это место выполняется, если XPos < 0
    15.             ; далее по смыслу выполняется qwerty2 (тут же, сразу после этого)
    16.         qwerty2:
    17.             ; это место выполняется всегда
    это не работает...
     
  17. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.347
    Конечно оно не будет работать, т.к. проблемный момент у тебя выше, чем ты показал. Ты выделяешь из lParam координаты и сохраняешь в переменные, а кто будет делать знаковое расширение word->dword?
    Почитай описание movsx
     
  18. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    shr замени на sar тогда можно будет отрицательные числа обрабатывать и замени
    на
     
  19. Qasm

    Qasm New Member

    Публикаций:
    0
    Регистрация:
    9 янв 2008
    Сообщения:
    14
    Вау! Работает!!! Всем огромное спасибо! Теперь я могу продолжить работу...