Сравнение двух целых чисел без сравнения - PullRequest
11 голосов
/ 25 января 2009

Можно ли найти наибольшее из двух целых чисел без какого-либо сравнения? Я нашел несколько решений:

if(!(a/b)) // if a is less than b then division result will be zero.
{
    cout << " b is greater than a";
}
else if (!(a-b)) // we know a is greater than or equal to b now.  check whether they are equal.
{
    cout << "a and b are equal";
}
else
    cout << "a is greater than b";

Но если (c) или if (! C) это сравнение с нулем. Кроме того, он не работает для отрицательных чисел. На самом деле мне нужно решение, которое избегает любого заявления if. Вместо этого я должен использовать операторы switch и арифметические операторы. Thanx.

Ответы [ 13 ]

36 голосов
/ 25 января 2009

Вычтите их и проверьте знак, используя мерзкие хитрые хаки
http://graphics.stanford.edu/~seander/bithacks.html

Не делайте этого в рабочем коде, если другие программисты знают, где вы живете.

5 голосов
/ 25 января 2009

Это забавная версия, в которой нет ничего условного.

int g = (int)"greater";
int l = (int)"less";
int e = (int)"equal";

int a = 7;
int b = 10;

char *result = (char*)((((a - b) >> 31) & l) | (((b - a) >> 31) & g) | ((~((a - b) | (b - a))) >> 31) & e);
cout << result;
2 голосов
/ 25 января 2009

Ни один из примеров, представленных в вопросе, или любой из ответов, которые пока не защищают от деления на ноль С какой стати вы пытаетесь избежать заявления «если»? Я подозреваю домашнее задание о?: Операторы.

cout << "Maximum is: " << ((a>b)?a:b)

Вот и мы.

Невозможно сравнить два числа без сравнения. Вы можете выдумать это и сделать косвенную операцию, но в конце дня вы что-то сравниваете. Доверьтесь компилятору для оптимизации кода и выбора лучших операций.

1 голос
/ 25 января 2009
char c;
c=0x3D + (!(b/a) && (a-b)) - (!(a/b) && (a-b));
printf("a %c b",c);
1 голос
/ 25 января 2009

Вы можете использовать тот факт, что знак вычисления a - b зависит от того, какое число больше. Это используется во многих реализациях сравнения. Но я верю, что вы никогда не сможете полностью избежать сравнения. В этом случае вам по крайней мере необходимо оценить содержимое флага знака на процессоре.

Если вам просто нужно отобразить нижнее число, вы также можете использовать арифметические трюки:

result = ((a + b) - sqrt((a - b) * (a - b))) / 2

РЕДАКТИРОВАТЬ эмм ... вам разрешено использовать switch?

Я должен использовать операторы switch и арифметические операторы.

switch в основном то же самое, что и цепочка if, и поэтому также использует сравнение. Это звучит так, как будто вы действительно должны просто сравнить с нулем, чтобы увидеть, какой знак имеет a - b.

0 голосов
/ 09 марта 2019

Чтобы получить наибольшее число без использования оператора сравнения / реляционного оператора

void PrintGreatestNumber(int a, int b)
{
   int [] x = new int[] { -1, 0, 1 };
   int greatestNumber =  ((a+b)+ x[ 1 + ((a-b) >> 31) - (-(a-b) >> 31)] * (a-b)) /2;  
   Console.WriteLine(greatestNumber);
}
0 голосов
/ 21 июня 2016

Я думаю, что этот метод лучше, чем другие, вы можете использовать эту логику c и java на обоих языках программирования, но int должен быть 4 байта, если int 2 байта, тогда сделать 15-байтовое смещение вправо вместо 31 байта.

enter code here

#include<stdio.h>

main()
{
   int a, b;
   printf("Enter three numbers\n");
   scanf("%d %d", &a, &b);
   printf("Largest number is %d \n",findMax( a,b ));
}
int findMax( int x, int y)
{
  int z = x - y;
  int i  = (z  >>  31)  &  0x1;
  printf("i = %d shift = %d \n", i, (z>>31));
  int  max  =  x - i  *  z;
  return max;
}
0 голосов
/ 14 октября 2013

Попробуй, проверил, хорошо работает.

public static int compare(int a, int b)
{
    int c = a - b;
    return (c >> 31) & 1 ^ 1;
}
0 голосов
/ 25 января 2009

Как бессмысленное упражнение, вот способ реализации функции cond - для достижения цели if, предполагая, что она (и switch, и ?:) каким-то образом исчезла из языка, и вы вы используете C ++ 0x.

void cond(bool expr, std::function<void ()> ifTrue, std::function<void ()> ifFalse)
{
    std::function<void ()> choices[2] = { ifTrue, ifFalse };
    choices[expr == false]();
}

, например

cond(x > y,
    /*then*/ [] { std::cout << "x is greater than y"; },
    /*else*/ [] { std::cout << "x is not greater than y"; });

Как я и говорю, бессмысленно.

0 голосов
/ 25 января 2009

Извращенная идея: использовать массив указателей на функции. Затем с помощью некоторых арифметических и побитовых операций получите индекс в этом массиве.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...