Сравнение двух целых чисел без сравнения

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

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) или если(!c) является сравнением с нулем. Кроме того, это не работает для отрицательных чисел. На самом деле мне нужно решение, которое избегает любого утверждения if. Вместо этого я должен использовать операторы Switch и арифметические операторы. ThanX.

12 ответов


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

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


вот забавная версия бит-twiddling, которая не имеет условных ветвей.

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;

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

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

там мы идем.

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


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

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

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

редактировать эээ ... ты разрешено использовать switch?

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

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


char c;
c=0x3D + (!(b/a) && (a-b)) - (!(a/b) && (a-b));
printf("a %c b",c);

(!(a/b) ?  cout << " b is greater than a" : (!(b-a) ? cout << "a and b are equal" :  cout << "a is greater than b") :  cout << "a is greater than b");

это становится немного грязным, хотя

Edit: это домашнее задание?


Я просто не вижу причин для этого : кто хотел бы программировать без "если"?

возможный ответ :

((a + b ) + abs (a-b ) ) / 2

Я думаю, что " abs "просто скрывает" если "где-то, так же как тернарный оператор, который является просто другим именем для" Если"...


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


как бессмысленное упражнение, вот способ реализации 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"; });

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


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

public static int compare(int a, int b)
{
    int c = a - b;
    return (c >> 31) & 1 ^ 1;
}

Я думаю, что этот метод лучше, чем другие, вы можете использовать эту логику 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;
}

void greater(int a, int b) {
    int c = a - b;
    switch(c) {
        case 0:
            cout << "a and b are equal" << endl;
            break;
        default:
            int d = c & (1<<31);
            switch(d) {
                case 0:
                    cout << "a is bigger than b" << endl;
                    break;
                default:
                    cout << "a is less than b" << endl;
            }
    }
}