Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.77/13: Рейтинг темы: голосов - 13, средняя оценка - 4.77
foo();
 Аватар для rattrapper
886 / 587 / 222
Регистрация: 03.07.2013
Сообщений: 1,549
Записей в блоге: 2
.NET 4.x

Побитовые операции с целыми числами

22.02.2014, 23:29. Показов 2818. Ответов 22
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть две переменные a и b. Обе задаются значениями в диапазоне [-1;1] включительно. Возможно ли какими нибудь операторами (всякими XOR и т.д.) заменить конструкцию
a == 0 ? b : a ;
Кажется что такое возможно, но не пойму как
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
22.02.2014, 23:29
Ответы с готовыми решениями:

Побитовые операции
Для двух символов реализовать операцию «И» два правых байт, получив таким образом значение для левого и правого байта нового символа. ...

Побитовые операции
Нужна помощь. впервые встречаюсь с побитовыми операциями. задания для меня, как минимум, непонятны. Читал теорию, но примеров...

Логические побитовые операции
Привет изучаю как работают логические операции а именно (XOR) Вот написал програмку которая заменяет один символ. static void...

22
 Аватар для ViterAlex
8951 / 4863 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
23.02.2014, 02:12
Т.е. если одна из переменных равна нулю, то использовать другую?
0
foo();
 Аватар для rattrapper
886 / 587 / 222
Регистрация: 03.07.2013
Сообщений: 1,549
Записей в блоге: 2
23.02.2014, 03:00  [ТС]
ViterAlex, да. Это возможно без условных операторов?
0
 Аватар для dirtez0
44 / 44 / 19
Регистрация: 20.01.2014
Сообщений: 87
23.02.2014, 03:06
по сути машина это делает при помощи алгебры логики примерно вот так:
Code
1
2
3
4
x = 1; // бит
 
// сравнение бита с нулем:
! (x ^ 1) // ^ - в данном случае означает логическое И (true только если оба оператора true). А оператор ! просто выполняет инверсию бита.
т.е сначала сравнивается 1 с 1, что дает 1 (true), по логике операции логического И, затем производится инверсия 1 (true) в 0 (false).
0
foo();
 Аватар для rattrapper
886 / 587 / 222
Регистрация: 03.07.2013
Сообщений: 1,549
Записей в блоге: 2
23.02.2014, 04:55  [ТС]
вроде у меня получилось:
a | (-a ^ b) & (a ^ b)
проверка
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Program
{
    static void Main(string[] args)
    {
        Func<int, int, int> expr = (a, b) =>
            a | (-a ^ b) & (a ^ b);
        Console.WriteLine(GenerateViriants().All(t => Check(t, expr))); \\True
        Console.ReadKey();
    }
    static IEnumerable<Tuple<int,int>> GenerateVariants()
    {
        var nums = Enumerable.Range(-1, 3);
        foreach (int a in nums)
            foreach (int b in nums)
                yield return new Tuple<int, int>(a, b);
    }
    static bool Check(Tuple<int, int> tpl, Func<int, int, int> expression)
    {
        int a = tpl.Item1, b = tpl.Item2;
        return (a == 0 ? b : a) == expression(a, b);
    }
}

такое выражение возможно укоротить?

Добавлено через 10 минут
dirtez0, позволю себе с Вами не согласиться
Цитата Сообщение от dirtez0 Посмотреть сообщение
^ - в данном случае означает логическое И
^ - аж никак ни логическое И, а исключающее ИЛИ!

Добавлено через 8 минут
dirtez0, Вашему вниманию предлагается:
C#
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
class Program
{
    static void Main(string[] args)
    {
        foreach (var t in GenerateVariants())
            Print((a, b) => a | b, '|', t);
        Console.WriteLine();
        foreach (var t in GenerateVariants())
            Print((a, b) => a & b, '&', t);
        Console.WriteLine();
        foreach (var t in GenerateVariants())
            Print((a, b) => a ^ b, '^', t);
        Console.ReadKey();
    }
    static IEnumerable<Tuple<int,int>> GenerateVariants()
    {
        var nums = Enumerable.Range(0, 2);
        foreach (int a in nums)
            foreach (int b in nums)
                yield return new Tuple<int, int>(a, b);
    }
    static void Print(Func<int,int,int> func, char f, Tuple<int,int> t)
    {
        int a = t.Item1, b = t.Item2;
        Console.WriteLine("{0} {1} {2} = {3}",
            a, f, b, func(a, b));
    }
}
Добавлено через 1 минуту
возвращаюсь к сабжу, можно ли укоротить выражение : a | (-a ^ b) & (a ^ b)
0
1195 / 588 / 88
Регистрация: 20.09.2012
Сообщений: 1,881
23.02.2014, 08:51
Цитата Сообщение от rattrapper Посмотреть сообщение
можно ли укоротить выражение : a | (-a ^ b) & (a ^ b)
Если в кол-ве буковок то a - a * a * b + b короче
1
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
23.02.2014, 16:14
rattrapper, только вот сравнение все равно быстрее, чуть ли не в один такт может сделать.
1
1195 / 588 / 88
Регистрация: 20.09.2012
Сообщений: 1,881
23.02.2014, 17:18
Цитата Сообщение от Psilon Посмотреть сообщение
только вот сравнение все равно быстрее
http://ideone.com/IPmG2G что я делаю не так?
1
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
23.02.2014, 18:14
pycture, неправильно считаете:
http://ideone.com/v9uCdG

забавно, что по времени одно и то же выходит
0
1195 / 588 / 88
Регистрация: 20.09.2012
Сообщений: 1,881
23.02.2014, 18:57
C#
1
2
3
 
Console.WriteLine("res1 = {0}", result[0].Average());
Console.WriteLine("res2 = {0}", result[0].Average());


ксати это еще более синтетический тест чем у меня

Добавлено через 18 минут
Моно как всегда работает как попало (видимо там компилятор в принципе ниче оптимизировать не в состоянии), а запуск под виндой
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
for (int i = 0; i < N; i++)
{
    var sw = Stopwatch.StartNew();
    int c = a1 == 0 ? b : a1;
    int d = a2 == 0 ? b : a2;
    sw.Stop();
    trash += c + d;
    result[0][i] = sw.ElapsedTicks;
 
    var sw2 = Stopwatch.StartNew();
    c = a1 - a1 * a1 * b + b;
    d = a2 - a2 * a2 * b + b;
    sw2.Stop();
    trash += c + d;
    result[1][i] = sw2.ElapsedTicks;
}
в большистве случаев показывает что арифметика незначительно быстрее перехода ( по крайней мере на моей машине)

Добавлено через 11 минут
Ну вот удалось привести моношную версию в чувство (путем избавления от бесполезных массивов) http://ideone.com/7zU8QK
Что в этом варианте я считаю неправильно ?
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
23.02.2014, 19:12
pycture,
ксати это еще более синтетический тест чем у меня
это называется кривая копи-паста.

Что в этом варианте я считаю неправильно ?
в этом - правильно Просто нужно смешанно считать, чтобы ликвидировать возможные аномалии, то есть в 1 цикле.

А так довольно интересный результат получился).

Ну вот удалось привести моношную версию в чувство (путем избавления от бесполезных массивов)
да я собирался исправить также, но пришлось переключиться на другую задачу (друг позвонил), но я рад, что мысли достойных сходятся

Добавлено через 3 минуты
rattrapper, кстати, задача случайно не из разряда "отсортировать по нескольким полям с помощью CompareTo"?

Добавлено через 58 секунд
pycture, энивей, хотя так и быстрее, лучше использовать понятную логику, а не магию и ловкость рук

Но это не умаляет ваших результатов.
2
1195 / 588 / 88
Регистрация: 20.09.2012
Сообщений: 1,881
23.02.2014, 19:37
Цитата Сообщение от Psilon Посмотреть сообщение
лучше использовать понятную логику
Здесь я полностью согласен.
Цитата Сообщение от Psilon Посмотреть сообщение
довольно интересный результат получился
Этому результату есть объяснение. В современных процессорах есть конвеер и предсказатель переходов. Если предсказатель промахивается конвеер вычищается, предвычесленные результаты в нем теряются и вычисления повторяются по другой ветке (с небольшими затратами по времени). При отсуствии условий и переходов, конвеер прет как танк и за счет этого может незначительно опережать вариант с переходом.
Но в условиях С# данный аспект почти не имеет практического применения, поэтому "лучше использовать понятную логику".
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
23.02.2014, 19:38
Цитата Сообщение от pycture Посмотреть сообщение
Что в этом варианте я считаю неправильно ?
Даете слишком большое раздолье компилятору для оптимизации путем расчета некоторых значений на стадии компиляции.

C#
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
using System;
using System.Linq;
using System.Collections.Generic;
using System.Threading;
using System.Diagnostics;
 
namespace A
{
    class Program
    {
        private const int N = 1000000;
 
        private static void Main(string[] args)
        {
            long trash = 0;
            int a1, a2, b;
            var result0 = 0.0;
            var result1 = 0.0;
            int c, d;
            for (int i = 0; i < N; i++)
            {
                Randomize(out a1, out a2, out b);
 
                var sw = Stopwatch.StartNew();
                c = a1 == 0 ? b : a1;
                d = a2 == 0 ? b : a2;
                sw.Stop();
                trash += c + d;
                result0 += (double)sw.ElapsedTicks;
 
                var sw2 = Stopwatch.StartNew();
                c = a1 - a1 * a1 * b + b;
                d = a2 - a2 * a2 * b + b;
                sw2.Stop();
                trash += c + d;
                result1 += (double)sw2.ElapsedTicks;
            }
            Console.WriteLine(trash);
            Console.WriteLine("res1 = {0}", result0 / N);
            Console.WriteLine("res2 = {0}", result1 / N);
 
        }   // your code goes here
 
        static void Randomize(out int a1, out int a2, out int b)
        {
            a1 = r.Next(0);
            a2 = r.Next(0) + 1;
            b = r.Next(0) + 1;
        }
 
        static readonly Random r = new Random();
    }
}
Метод Randomize каждый раз "генерирует" те же самые значения (0, 1, 1), но компилятор уже не лезет с оптимизациями.

Было:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  IL_001e:  call       class [System]System.Diagnostics.Stopwatch [System]System.Diagnostics.Stopwatch::StartNew()
  IL_0023:  stloc.s    sw2
  IL_0025:  ldc.i4.1
  IL_0026:  stloc.3
  IL_0027:  ldc.i4.1
  IL_0028:  stloc.s    d
  IL_002a:  ldloc.s    sw2
  IL_002c:  callvirt   instance void [System]System.Diagnostics.Stopwatch::Stop()
...
  IL_0045:  call       class [System]System.Diagnostics.Stopwatch [System]System.Diagnostics.Stopwatch::StartNew()
  IL_004a:  stloc.s    sw
  IL_004c:  ldc.i4.1
  IL_004d:  stloc.3
  IL_004e:  ldc.i4.1
  IL_004f:  stloc.s    d
  IL_0051:  ldloc.s    sw
  IL_0053:  callvirt   instance void [System]System.Diagnostics.Stopwatch::Stop()
Стало:
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
  IL_002f:  call       class [System]System.Diagnostics.Stopwatch [System]System.Diagnostics.Stopwatch::StartNew()
  IL_0034:  stloc.s    sw2
  IL_0036:  ldloc.1
  IL_0037:  ldloc.1
  IL_0038:  ldloc.1
  IL_0039:  mul
  IL_003a:  ldloc.3
  IL_003b:  mul
  IL_003c:  sub
  IL_003d:  ldloc.3
  IL_003e:  add
  IL_003f:  stloc.s    c
  IL_0041:  ldloc.2
  IL_0042:  ldloc.2
  IL_0043:  ldloc.2
  IL_0044:  mul
  IL_0045:  ldloc.3
  IL_0046:  mul
  IL_0047:  sub
  IL_0048:  ldloc.3
  IL_0049:  add
  IL_004a:  stloc.s    d
  IL_004c:  ldloc.s    sw2
  IL_004e:  callvirt   instance void [System]System.Diagnostics.Stopwatch::Stop()
...
  IL_006a:  call       class [System]System.Diagnostics.Stopwatch [System]System.Diagnostics.Stopwatch::StartNew()
  IL_006f:  stloc.s    sw
  IL_0071:  ldloc.1
  IL_0072:  brfalse.s  IL_0077
  IL_0074:  ldloc.1
  IL_0075:  br.s       IL_0078
  IL_0077:  ldloc.3
  IL_0078:  stloc.s    c
  IL_007a:  ldloc.2
  IL_007b:  brfalse.s  IL_0080
  IL_007d:  ldloc.2
  IL_007e:  br.s       IL_0081
  IL_0080:  ldloc.3
  IL_0081:  stloc.s    d
  IL_0083:  ldloc.s    sw
  IL_0085:  callvirt   instance void [System]System.Diagnostics.Stopwatch::Stop()
http://ideone.com/OJn3kl
0
1195 / 588 / 88
Регистрация: 20.09.2012
Сообщений: 1,881
23.02.2014, 19:56
Цитата Сообщение от kolorotur Посмотреть сообщение
Даете слишком большое раздолье компилятору для оптимизации путем расчета некоторых значений на стадии компиляции.
Стало
Ситуацию не меняет. Под виндой версия с арифметикой в 6-ти запусках из 10 опережает переход.
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
23.02.2014, 20:03
Цитата Сообщение от pycture Посмотреть сообщение
Под виндой версия с арифметикой в 6-ти запусках из 10 опережает переход
У меня результат прямо противоположный.
Самый близкий результат — 1мс в пользу проверки, а так опережает на 7-8мс стабильно.

По ссылке тоже, но там не пойми какой компилятор и на чем выполнение.
0
1195 / 588 / 88
Регистрация: 20.09.2012
Сообщений: 1,881
23.02.2014, 20:11
Цитата Сообщение от kolorotur Посмотреть сообщение
Самый близкий результат — 1мс в пользу проверки, а так опережает на 7-8мс стабильно.
А в % это сколько?
У меня результат прямо противоположный
Это много от чего зависит, от процессора (и крутости его предсказателя), от системы, от текущей загрузки.
Можете попробывать убрать вызов Randomize из тела цикла
C#
1
2
3
4
5
6
7
8
9
for (int i = 0; i < N; i++)
{
    //Randomize(out a1, out a2, out b);
    a1 = r.Next(0);
    a2 = r.Next(0) + 1;
    b = r.Next(0) + 1;
 
    var sw = Stopwatch.StartNew();
....
Лишние переходы в этом тесте ему на пользу не идут.
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
23.02.2014, 20:16
pycture, Randomize не учитывается в stopwatch, поэтому он наоборот дает более чистые результаты.
0
1195 / 588 / 88
Регистрация: 20.09.2012
Сообщений: 1,881
23.02.2014, 20:17
Цитата Сообщение от Psilon Посмотреть сообщение
Randomize не учитывается в stopwatch
Дело не в stopwatch, дело в конвеере.

Добавлено через 1 минуту
Цитата Сообщение от Psilon Посмотреть сообщение
поэтому он наоборот дает более чистые результаты
И если не учитывается, то как дает более чистые результаты ?
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
23.02.2014, 20:18
При чем тут конвеер? Мы же пытаемся понять для любых чисел...

И да, все методы с телом менее 4 строк автоматически инлайнятся. Так что разницы не будет.
0
1195 / 588 / 88
Регистрация: 20.09.2012
Сообщений: 1,881
23.02.2014, 20:26
Цитата Сообщение от Psilon Посмотреть сообщение
При чем тут конвеер. Мы же пытаемся понять для любых чисел...
Причем конвеер я писал выше. А числа тут причем?
Цитата Сообщение от Psilon Посмотреть сообщение
И да, все методы с телом менее 4 строк автоматически инлайнятся
У меня не инлайнятся (net 4, studio 2013, x64, Release, [x]Optimize Code)
Code
1
2
3
4
5
6
7
8
        IL_0021: ldloca.s a1
        IL_0023: ldloca.s a2
        IL_0025: ldloca.s b
        IL_0027: call void A.Program::Randomize(int32&, int32&, int32&)
        IL_002c: call class [System]System.Diagnostics.Stopwatch [System]System.Diagnostics.Stopwatch::StartNew()
        IL_0031: stloc.s sw
        IL_0033: ldloc.1
        IL_0034: brfalse.s IL_0039
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
23.02.2014, 20:26
Помогаю со студенческими работами здесь

Побитовые операции с double
Нашел на msdn Почему так? А если мне надо побитово что-то с ним сделать? BitConverter'ом пользоваться?..

Побитовые операции - сдвиг
Вот код. Объясните пожалуйста,почему так ведёт себя последний цикл. Как-то он странно сдвигает. /* * Created by SharpDevelop. *...

побитовые операции
кто сможет помоч с решением: преобразовать беззнаковое целое число по следующему закону:первый и последний бит не изменяются,бит между...

Побитовые операции
С целью трассировки приложения предусмотреть вывод промежуточных результатов на каждом шаге. Например, вывод исходного символа, его кода,...

Побитовые операции для вывода символа
форма символа кодируется последовательностью из 8 байтов. необходимо программно разложить каждый байт на 0 и 1, в случае 1 выводить символ...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! */ #include <iostream> #include <stack> #include <cctype>. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru