Проверка четности числа a&1 vs a%2 что быстрее

Тема в разделе "WASM.BEGINNERS", создана пользователем MEPOX, 11 май 2010.

  1. MEPOX

    MEPOX New Member

    Публикаций:
    0
    Регистрация:
    15 авг 2008
    Сообщения:
    259
    Ну проверка четности числа. Что лучше традиционный if(a%2==0) (ну или != если более вероятно) или if(a&1==0)? или вот такое:
    #include <stdio.h>
    main(a,b){a=2,b=3;printf("%d,%d",a&0x1,b&0x1);}
    ЗЫ просто 0x1 прикольнее смотрицо ^_^
     
  2. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    монописсуально.
    оптимизация превратит это в один код.
     
  3. VaZoNeZ

    VaZoNeZ New Member

    Публикаций:
    0
    Регистрация:
    12 июл 2009
    Сообщения:
    121
    Сильно сказано )
     
  4. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    Если a - беззнаковая переменная, то a%2 и a&1 - одно и то же (если не считать синтаксических различий типа того, что у & приоритет ниже плинтуса). Если a - знаковая, то это не одно и то же (-1%2 == -1, хотя см.ниже), а сумеет ли компилятор догадаться, что при сравнении с нулём это неважно, - зависит от компилятора.

    Стандарты говорят следующее:
    ISO/IEC 14882:2003 aka C++03, раздел 5.6 "Multiplicative operators":
    то есть формально в C++ (-1%2) - это UB. Однако после цитаты выше в стандарте есть сноска:
    ISO/IEC 9899:1999 aka C99 строже, раздел 6.5.5 "Multiplicative operators":
    То есть в C (-1%2)==-1. Естественно, в такой ситуации издеваться над разработчиками авторы компиляторов не станут и -1%2==-1 таки везде.

    В реальной жизни дела обстоят так.
    Код (Text):
    1. #include <stdio.h>
    2. void printodd(int a)
    3. {
    4.     if (a%2)
    5.         printf("odd\n");
    6.     else
    7.         printf("even\n");
    8. }
    Компилятор из 2008-й студии честно вычисляет остаток a%2:
    cl /O2 /c 1.cpp && dumpbin /disasm 1.obj
    Код (Text):
    1.   00000000: 8B 44 24 04        mov         eax,dword ptr [esp+4]
    2.   00000004: 25 01 00 00 80     and         eax,80000001h
    3.   00000009: 79 05              jns         00000010
    4.   0000000B: 48                 dec         eax
    5.   0000000C: 83 C8 FE           or          eax,0FFFFFFFEh
    6.   0000000F: 40                 inc         eax
    7.   00000010: 74 0D              je          0000001F
    8.   00000012: C7 44 24 04 00 00  mov         dword ptr [esp+4],offset ??_C@_04CDMKADFM@odd?6?$AA@
    9.             00 00
    10.   0000001A: E9 00 00 00 00     jmp         _printf
    11.   0000001F: C7 44 24 04 00 00  mov         dword ptr [esp+4],offset ??_C@_05NEMINMEL@even?6?$AA@
    12.             00 00
    13.   00000027: E9 00 00 00 00     jmp         _printf
    У g++ 4.2.1 хватает ума на оптимизацию сравнения с нулём:
    g++ -O3 -c 1.cpp && objdump --disassemble -m intel 1.o
    Код (Text):
    1.    0:   83 e7 01                and    edi,0x1
    2.    3:   74 0b                   je     10 <_Z8printoddi+0x10>
    3.    5:   bf 00 00 00 00          mov    edi,0x0
    4.    a:   e9 00 00 00 00          jmp    f <_Z8printoddi+0xf>
    5.    f:   90                      nop
    6.   10:   bf 00 00 00 00          mov    edi,0x0
    7.   15:   e9 00 00 00 00          jmp    1a <_Z8printoddi+0x1a>
    (релоки в командах 5,a,10,15 отобразились как нули).
     
  5. JhanGhuangxi

    JhanGhuangxi New Member

    Публикаций:
    0
    Регистрация:
    15 апр 2010
    Сообщения:
    31
    монопениссуально выглядит точнее ;))))
     
  6. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Нет a%2, часто очень медленно.
     
  7. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.890
    а вот так вычислить четность некошерно?
    Код (Text):
    1. shr a,1
    2. jnc число_а_четное
    3. число_а_нечетное: ...
     
  8. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    логические операции разве не быстрее сдвиговых?
     
  9. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    Mikl___
    Это изменит значение а, лучше так (FASM):
    Код (Text):
    1. test   [a], 1
    2. jnz    .odd_value