Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 38, средняя оценка - 4.82
AvengerAlive
5 / 5 / 0
Регистрация: 30.07.2011
Сообщений: 257
#1

Проверка числа на чётность - C++

29.08.2011, 20:34. Просмотров 5269. Ответов 13
Метки нет (Все метки)

Какой из этих способов работает быстрее
C++
1
if (!(a%2))
или
C++
1
if (!(a&1))
0
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
29.08.2011, 20:34
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Проверка числа на чётность (C++):

Проверка числа на чётность/нечётность - C++
Подскажите пожалуйста молодому-неопытному как проверить в С++ чётное число или нечётное? Есть какя-то специальная функция?

Проверка введенного числа на чётность - C++
Написать программу, которая проверяет, является ли введенное пользователем целое число четным. Хэлп ми плз )

Проверка числа типа double на чётность/нечётность - C++
В программе необходимо проверить число типа double на то, является оно четным или нет. Это возможно как-то сделать или нет? Обычный метод,...

Итератор и проверка на чётность/нечётность - C++
Добрый день. Не получается организовать проверку на нечётное количество. При вводе нечётного количества данных программа выдаёт ошибку....

Проверка чисел на чётность или наоборот, дальнейший вывод - C++
Написать программу, в которой вводятся 3 числа: А,В,С. Если среди них имеется хотя бы одно четное вычислить максимальное, иначе –...

Определить чётность числа - C++
Кто чем может Зачет скоро, а все сам сделать не успеваю. Все задания этого пункта нужно выполнить, используя оператор switch. 1....

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
grizlik78
Эксперт С++
1911 / 1443 / 112
Регистрация: 29.05.2011
Сообщений: 3,000
29.08.2011, 20:37 #2
На подавляющем числе всевозможных компиляторов — одинаково. В клинических случаях второй быстрее.
1
AvengerAlive
5 / 5 / 0
Регистрация: 30.07.2011
Сообщений: 257
29.08.2011, 20:39  [ТС] #3
То есть если есть огромный поток чисел, то лучше второй?
0
grizlik78
Эксперт С++
1911 / 1443 / 112
Регистрация: 29.05.2011
Сообщений: 3,000
29.08.2011, 20:42 #4
Ну, если найдешь компилятор, который генерирует здесь разный код, то наверное.
0
ISergey
Maniac
Эксперт С++
1374 / 885 / 52
Регистрация: 02.01.2009
Сообщений: 2,658
Записей в блоге: 1
29.08.2011, 20:45 #5
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
AvengerAlive, А ты как думаешь?

C++
1
2
3
4
5
6
7
8
9
__declspec(noinline) int f_1(int n)
{
    return n % 2;
}
 
__declspec(noinline) int f_2(int n)
{
    return n & 1;
}
Для первого случая..
Assembler
1
2
3
4
5
6
00FF1000 25 01 00 00 80       and         eax,80000001h  
00FF1005 79 05                jns         f_1+0Ch (0FF100Ch)  
00FF1007 48                   dec         eax  
00FF1008 83 C8 FE             or          eax,0FFFFFFFEh  
00FF100B 40                   inc         eax  
00FF100C C3                   ret
Для второго
Assembler
1
2
00FF1010 83 E0 01             and         eax,1  
00FF1013 C3                   ret
3
Thinker
Эксперт C++
4226 / 2200 / 150
Регистрация: 26.08.2011
Сообщений: 3,802
Записей в блоге: 5
29.08.2011, 20:45 #6
Если есть возможность, работайте с битами, во многих случаях полезно.

Не по теме:

Как у вас с полем дело обстоит?

0
grizlik78
Эксперт С++
1911 / 1443 / 112
Регистрация: 29.05.2011
Сообщений: 3,000
29.08.2011, 20:49 #7
ISergey, сравнение не совсем честное, так как результаты этих функций могут различаться, тогда как логическое отрицание даёт одинаковый результат.
0
ISergey
Maniac
Эксперт С++
1374 / 885 / 52
Регистрация: 02.01.2009
Сообщений: 2,658
Записей в блоге: 1
29.08.2011, 21:01 #8
В любом случаи второй вариант быстрее.
Для такого кода
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
 
__declspec(noinline) int f_1(int n)
{
    return !(n % 2);
}
 
__declspec(noinline) int f_2(int n)
{
    return !(n & 1);
}
 
int main()
{
    int x; std::cin >> x; // Чтобы компилятор не перестарался с оптимизацией.. 
 
    int a = f_1(x);
    int b = f_2(x);
 
 
    std::cout << a << b; // Это тоже..
    return 0;
}
Получим
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
    13: int main()
    14: {
01191030 55                   push        ebp  
01191031 8B EC                mov         ebp,esp  
01191033 51                   push        ecx  
    15:     int x; std::cin >> x;
01191034 8B 0D 48 20 19 01    mov         ecx,dword ptr [__imp_std::cin (1192048h)]  
0119103A 8D 45 FC             lea         eax,[x]  
0119103D 50                   push        eax  
0119103E FF 15 44 20 19 01    call        dword ptr [__imp_std::basic_istream<char,std::char_traits<char> >::operator>> (1192044h)]  
    16: 
    17:     int a = f_1(x);
01191044 8B 4D FC             mov         ecx,dword ptr [x]  
01191047 8B C1                mov         eax,ecx  
01191049 E8 B2 FF FF FF       call        f_1 (1191000h)  
0119104E 8B D0                mov         edx,eax  
    18:     int b = f_2(x);
01191050 8B C1                mov         eax,ecx  
01191052 E8 C9 FF FF FF       call        f_2 (1191020h)  
    19: 
    20: 
    21:     std::cout << a << b;
01191057 8B 0D 50 20 19 01    mov         ecx,dword ptr [__imp_std::cout (1192050h)]  
0119105D 50                   push        eax  
0119105E 52                   push        edx  
0119105F FF 15 4C 20 19 01    call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (119204Ch)]  
01191065 8B C8                mov         ecx,eax  
01191067 FF 15 4C 20 19 01    call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (119204Ch)]  
    22:     return 0;
0119106D 33 C0                xor         eax,eax  
    23: }
0119106F 8B E5                mov         esp,ebp  
01191071 5D                   pop         ebp  
01191072 C3                   ret  
.....
 
     8: __declspec(noinline) int f_2(int n)
     9: {
    10:     return !(n & 1);
01191020 F7 D0                not         eax  
01191022 83 E0 01             and         eax,1  
    11: }
01191025 C3                   ret  
.....
     3: __declspec(noinline) int f_1(int n)
     4: {
     5:     return !(n % 2);
01191000 25 01 00 00 80       and         eax,80000001h  
01191005 79 05                jns         f_1+0Ch (119100Ch)  
01191007 48                   dec         eax  
01191008 83 C8 FE             or          eax,0FFFFFFFEh  
0119100B 40                   inc         eax  
0119100C F7 D8                neg         eax  
0119100E 1B C0                sbb         eax,eax  
01191010 40                   inc         eax  
     6: }
01191011 C3                   ret
0
grizlik78
Эксперт С++
1911 / 1443 / 112
Регистрация: 29.05.2011
Сообщений: 3,000
29.08.2011, 21:05 #9
ISergey, неужто микрософт?
кстати, а оптимизация была включена?
0
ISergey
Maniac
Эксперт С++
1374 / 885 / 52
Регистрация: 02.01.2009
Сообщений: 2,658
Записей в блоге: 1
29.08.2011, 21:12 #10
Цитата Сообщение от grizlik78 Посмотреть сообщение
ISergey, неужто микрософт?
Угу
Цитата Сообщение от grizlik78 Посмотреть сообщение
кстати, а оптимизация была включена?
Да. Я ведь спецом добавил int x; std::cin >> x; int a = f_1(x);
что бы компилятор не разошелся..
просто когда так написал
C++
1
int a = f_1(10);
Компилятор не растерялся и выдал мне
Assembler
1
2
3
4
5
6
     3: __declspec(noinline) int f_1(int n)
     4: {
     5:     return !(n % 2);
008C1000 B8 01 00 00 00       mov         eax,1  
     6: }
008C1005 C3                   ret
0
iama
1250 / 975 / 49
Регистрация: 30.07.2010
Сообщений: 5,297
29.08.2011, 21:13 #11
grizlik78, битовые операции априори должны выполняться быстрее простой арифметики, раз уж во всех ЭВМ используется двоичная система счисления, разве нет?
0
grizlik78
Эксперт С++
1911 / 1443 / 112
Регистрация: 29.05.2011
Сообщений: 3,000
29.08.2011, 21:23 #12
Цитата Сообщение от iama Посмотреть сообщение
grizlik78, битовые операции априори должны выполняться быстрее простой арифметики, раз уж во всех ЭВМ используется двоичная система счисления, разве нет?
Ну я же не говорил, что !(a%2) может оказаться быстрее
Просто это тот случай, когда это выражение легко сводится как раз к битовым операциям.

Цитата Сообщение от ISergey Посмотреть сообщение
Угу
Чёрт, я думал, что моё мнение о MSVC не может стать ещё хуже. Я ошибся
Ну хоть в случае unsigned он понимает, что (unsigned(a)%2) и (unsigned(a)&1) это одно и то же?
0
iama
1250 / 975 / 49
Регистрация: 30.07.2010
Сообщений: 5,297
29.08.2011, 21:55 #13
Цитата Сообщение от grizlik78 Посмотреть сообщение
Просто это тот случай, когда это выражение легко сводится как раз к битовым операциям.
Выходит, у тебя завышеные ожидания, а у меня - заниженые
0
grizlik78
Эксперт С++
1911 / 1443 / 112
Регистрация: 29.05.2011
Сообщений: 3,000
29.08.2011, 22:06 #14
Да уж. Про ожидания.
Я тут тоже немножко поэкспериментировал c GCC.
Если оптимизацию не включать, то код получается одинаковым. Отбросив лишнее, получается так:
Assembler
1
2
3
4
5
    movl    -4(%rbp), %eax
    andl    $1, %eax
    testl   %eax, %eax
    sete    %al
    movzbl  %al, %eax
Что ж, это вписывается в мои ожидания. В обоих случаях главная операция "and 1"
Однако после включения оптимизации компилятор меня несколько озадачил.
Функция f_1:
Assembler
1
2
3
    xorl    %eax, %eax
    testb   $1, %dil
    sete    %al
Функция f_2
Assembler
1
2
3
    movl    %edi, %eax
    andl    $1, %eax
    xorl    $1, %eax
Шутники

Добавлено через 3 минуты
Да, то была оптимизация по скорости (-O2 или -O3)
При оптимизации по размеру (-O1) код функций снова становится одинаковым
Assembler
1
2
3
    testb   $1, %dil
    sete    %al
    movzbl  %al, %eax
2
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.08.2011, 22:06
Привет! Вот еще темы с ответами:

Чётность трёх чисел - C++
Помогите пожалуйста написать программу, которая выводит &quot;Да&quot; или &quot;Нет&quot; в зависимости от того имеют ли три заданных числа одинаковую...

Возведение числа в степень и проверка числа на четность - C++
Добрый вечер что то вообще не понял эту тему помогите пожалуйста С помощью директивы #define написать следующие макросы: a) возведение...

Программа для проверки цифр в числе на чётность - C++
как проверить каждую цифру в четырёхзначном числе на чётность без массива в DevC++ Я написал программу, которая делает это действие в...

Используя алгоритм adjacent_find, обнулить первую пару соседних элементов вектора, имеющих одинаковую чётность - C++
Дан вектор V. Обнулить первую пару соседних элементов, имеющих одинаковую четность. Например, список 1, 2, 3, 4, 6, 8, 3, 1 должен быть...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
29.08.2011, 22:06
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru