2009-11-16 14 views
6

Qualcuno può dirmi come scrivere un programma C per confrontare i numeri (compresi i numeri negativi) senza utilizzare operatori logici?Programma C per confrontare gli interi senza utilizzare operatori logici?

+4

Che cosa vuoi ottenere esattamente come risultato? –

+1

Sono abbastanza certo che si tratta di un dup, ma non riesco a trovare la domanda precedente. Considerando l'altra domanda ha una soluzione esplicitamente codificata, probabilmente è una buona cosa. – outis

+0

Come menzionato da Sam152, puoi sempre scrivere un testo per l'uguaglianza con XOR (^ operatore in C). se (a^b == 0) -> sono uguali –

risposta

4

Ecco un programma che confronta i due numeri senza utilizzare gli operatori di relazione (funziona anche con numeri negativi). controlla.

/------ programma C -------/

void main() 
{ 
    int a,b,c,temp; 
    printf("enter a and b:"); 
    scanf("%d%d",&a,&b); 
    c=a-b; 
    temp=c+abs(c);  // to check if the difference is negative or not 
    if(temp==0) 
    printf("a is smaller than b"); 
    else 
    printf("a is bigger than b"); 
    getch(); 
    } 

EDIT: codice rivisto di Maddy (dal suo commento qui sotto) segue.

void main() { 
    int a,b,c,d,temp; 
    printf("enter a and b:"); 
    scanf("%d%d",&a,&b); 
    c=a-b; 
    d=abs(c); 
    temp=c+d; 
    if (c==0) printf("a is equal to b"); 
    else if(temp==0) printf("a is smaller than b"); 
    else printf("a is bigger than b"); 
    printf("%d",d); getch(); 
} 

Penso che ora il codice funziona bene per tutti gli ingressi ...

+3

Dare una soluzione completa, anche se non corretta, a una domanda a casa non è mai buona. Da qui il voto negativo. – Paulius

+0

Il codice sopra riportato funziona bene. Non ho capito qual è il problema con questo codice? – Madhan

+1

@Paulius: in effetti questo non è corretto, ma si noti che è l'OP che ha pubblicato questa risposta. – Stephan202

8

Sì, puoi sottrarli e osservare la differenza.

Lo so, questo porta alla domanda successiva: come puoi sapere se la differenza è < 0, = 0 o> 0? Bene, puoi occuparti di < 0 controllando se il bit di segno è impostato.

+0

Che porta alla domanda: come controllare la differenza senza operatori logici;) – Stephan202

+1

signore può mostrare al programma come può essere. – Madhan

+14

No. Non voglio fare i compiti. –

1

Supponiamo di avere int x e int y. Sia int z = x-y, e poi ripetutamente (31 o 63 volte a seconda delle preferenze) prendi z | = z < < 1 e z | = z >> 1. Se la differenza è zero, z = 0 e se la differenza è diversa da zero, z = -1. Aggiungi da uno a z e usalo per indicizzare in una matrice di puntatori di funzione che contengono le istruzioni che vuoi seguire in ciascun caso.

È possibile eseguire questa operazione in modo più efficiente se è possibile utilizzare l'assemblaggio, ma poiché questo non sembra un problema pratico, non penso che tali soluzioni valgano la pena di esplorarle troppo profondamente. Se volevi una soluzione pratica, dovresti semplicemente utilizzare gli operatori logici :)

Ora, la dichiarazione del problema è molto discutibile in quanto l'aritmetica del computer viene definita utilizzando "operatori logici" ma se si assume ingenuamente (come probabilmente ti vogliono a) che quello che scrivi è quello che usi, la soluzione di cui sopra dovrebbe essere sufficiente.

EDIT: È NON necessario utilizzare if/else. Se il segno del confronto è importante, portare il segno nella posizione 2s e usarlo per indicizzare in una matrice di puntatore a funzione.

+0

L'ultima frase è un suggerimento intelligente, +1. –

7

Non abbiamo intenzione di fare i compiti, ma lasciatemi aggiungere alcuni suggerimenti su come procedere. Partiamo dal presupposto che stiamo andando a confrontare a e b.

  1. Come Carl states, si consiglia di guardare la differenza d = a - b.
    • Osservazione: d può essere negativo, zero o positivo.
    • Domanda: quale valore di d corrisponde alla quale (dis) uguaglianza di un e b?
  2. Una volta calcolato d e sa come interpretarlo, è necessario trovare il modo per controllarli senza l'utilizzo di operatori logici.
    • Osservazione: i candidati evidenti sono bitwise operators.
    • Domanda: ma in che modo i computer (di solito) memorizzano numeri interi?
    • Suggerimento: dare un'occhiata a two's complement.
    • Domanda: come si può distinguere tra un numero negativo e un numero non negativo?
  3. Ora avete tutte le informazioni necessarie per rispondere alla domanda.
    • Suggerimento: sei, naturalmente, ha permesso di utilizzare if e else dichiarazioni.
    • Suggerimento: si consiglia di utilizzare INT_MIN da limits.h.

Edit: questa risposta, e la maggior parte delle altre risposte qui per scontato che il PO non è consentito utilizzare logical e relational (confronto) operatori. Tuttavia, l'OP menziona esplicitamente che gli operatori logici non sono consentiti. Penso che la ragione principale di questo equivoco sia il fatto che il problema è banale da risolvere usando operatori di confronto.

3

È possibile utilizzare gli operatori relazionali (<,>, < =,> =) e/o gli operatori di uguaglianza (== ,! =).

+0

+1: solo ora noto che l'OP non li esclude. Mi chiedo se abbiamo collettivamente interpretato male la domanda, o che l'OP non ha dichiarato correttamente il suo incarico. (Sono propenso a optare per quest'ultimo.) – Stephan202

+0

Vedi la mia seconda soluzione, vicino al fondo. Sono d'accordo sul fatto che probabilmente abbiamo fatto un grosso problema con una domanda quasi banale. Vergogna su di noi! Err, tu! –

+0

Sono andato anche per quest'ultimo, ma volevo comunque vedere una rigorosa risposta letterale qui. E forse sottolinea l'inutilità di un simile esercizio. (Ora, se la domanda avesse detto "complemento a complemento di due complementi" o "logica aritmetica" invece di "C", sarebbe stata un'altra questione.) – aib

-1

Ecco un programma che confronta i due numeri senza utilizzare operatori di relazione (funziona anche con numeri negativi).

void main() 
{ 
    int a,b,c,d,temp; 
    printf("enter a and b:"); 
    scanf("%d%d",&a,&b); 
    c=a-b; 
    d=abs(c); 
    temp=c+d; 
    if(c==0) 
     printf("a is equal to b"); 
    else if(temp==0) 
     printf("a is smaller than b"); 
    else 
     printf("a is bigger than b"); 
    printf("%d",d); 
    getch(); 
} 

Penso che ora il codice funziona bene per tutti gli ingressi ...

+0

@Maddy: seleziona il tuo codice e premi 'ctrl + k' per formattare correttamente è qui su SO. Inoltre, per favore indentate correttamente (come ho fatto per voi). – Stephan202

+0

@Maddy, inoltre, la prossima volta si prega di aggiornare/modificare la risposta precedente invece di postarne una nuova. – Stephan202

+0

@stephan ok signore, come sono nuovo a questo non lo so. da ora in poi, lo seguirò. Grazie. – Madhan

1

Tenete a mente che operatore logico sono molto più veloce di operatori aritmetici.

Come risposta per voi ...

if(x-y){ elements are different}else{ they are equals} 
+1

Sei sicuro di questa affermazione? In una CPU moderna, la maggior parte del rithmetic (tutto?) Intero viene eseguita in 1 ciclo, mentre la logica di solito significa saltare e saltare di solito significa condutture scaricate. –

+0

effettivamente no :) le istruzioni JMP vengono rilevate dal predittore di branche nella CPU e sono prefecate anche prima dell'esigenza di esecuzione. L'aritmetica è più veloce per 8-32bytes, perché MMX è in realtà più lento (non è proprio sicuro, ma suppongo che sarebbe facile scoprirlo) "Condotte scaricate" si verifica quando chiamate Doiung, non salti locali (piccoli). – Quamis

24

Questo è il gemello cattivo di Carl, qui per dirvi che sei smidollati tutto gracile!

Ecco una soluzione che non solo senza operatori logici, ma anche senza operatori relazionali (compresi ==) e senza if. Solo aritmetica e indicizzazione, piccola!

#include "stdio.h" 
#include "limits.h" 
int sign(int number) { 
    return (unsigned) number/(unsigned) INT_MIN; 
} 
int main(int argc, char *argv[]) { 
    int a = atoi(argv[1]); 
    int b = atoi(argv[2]); 
    int dif = a - b; 
    int sb1 = sign(dif); 
    int sb2 = sign(dif - 1) - sb1; 
    int ptr = 2 * sb2 + sb1; 
    char *messages[3] = { 
    "%d is greater than %d", 
    "%d is less than %d", 
    "%d is equal to %d" }; 
    printf(messages[ptr], a, b); 
} 

Alcuni risultati dei test:

$ ./compare 42 69 
42 is less than 69 

$ ./compare 69 42 
69 is greater than 42 

$ ./compare 42 -15 
42 is greater than -15 

$ ./compare 999 999 
999 is equal to 999 

$ ./compare -9 -10 
-9 is greater than -10 

La domanda iniziale, d'altra parte, è molto più facile. Gli operatori logici sono solo !, &, &&, |, || e !.Penso che un paio di if s annidati lo farebbero facilmente.

+4

+1 Perché mi piace questa soluzione in quanto non usa 'se' che sembra imbrogliare. –

+0

Sono tentato di non votare -1 dato che hai nascosto la tua logica condizionale all'interno dell'implementazione di 'sign (x)'. Cosa pensi che 'sign (x)' fa? AFAIK, non esiste un'implementazione intrinseca che faccia questo senza logica "operatore logico" (condizionale?). –

+0

@ Mark Lakata: so * esattamente * quale segno() fa, almeno nel mio programma! Se dovessi leggere il mio codice con più attenzione (righe 3-5), lo vedresti anche tu. –

0

Prova questo:

if(a-b) 
    printf("They are not equal"); 
else 
    printf("They are equal"); 
-1
int a = 2; 
int b = 1; 

int c = a - b; 

switch(c) 
{ 
    case 0: 
     System.out.println("equal"); 
    break; 

    default: 
     int min = Math.min(a, b); 

     switch(a - min) 
     { 
      case 0: 
       System.out.println("a lesser than b"); 
      break; 
      default: 
       System.out.println("a greater than b"); 
     } 
} 

Con la prima sottrazione viene controllato se i due numeri sono uguali, perché a-b=0 solo se a e b sono gli stessi. Quindi siamo nel caso predefinito del primo interruttore solo se a e b sono diversi.
ora in corso il min da a e b (qui è il trucco, c'è un implicito se con gli operatori logici all'interno della funzione Math.min) siamo in grado di sottrarre a con questo min. Se il risultato è 0 significa che a è minore di b.
L'ultimo caso è il rimanente, quindi a maggiore di b. Con le lingue che accettano numeri interi nella clausola if (0 ->false, altro->true) è possibile utilizzare if anziché switch (non per java).

+0

Probabilmente dovresti spiegare il tuo codice. – md5

+0

Fatto :) È chiaro? –

+0

È C#? C non ha 'System.out.println' o' Math.min'. –

-1

Buono. a-b è ovvio, ma poi verificare se a<b o a>b mi ha fermato per un po ', se non si usano anche le maschere di bit ... È bello tornare a cose del genere una volta ia mentre, fa sì che l'esperienza impedisca di cercare alternative soluzioni. ;) Ecco quello che mi si avvicinò con:

// -1 means a<b; 0 means a=b; 1 means a>b 
char cmp(double a, double b) 
{ 
    // (diff-1)/diff gives 1 or 2 if diff < 0 (e.g. -2/-1) = then a<b; 0 otherwise = a>b : 
    return (a = a - b) 
     ? (int)((a - 1)/a) ? -1 : 1 
     : 0; 
} 
+0

Più luoghi per comportamento non definito e altri problemi. – Olaf

0

Se non ti dispiace un inefficiente ciclo while i seguenti lavori ragionevolmente bene ed è semplice da leggere. XOR gli input e quindi sposta la risposta finché il risultato non è 1 o 0 (non una corrispondenza o una corrispondenza).

#include <stdio.h> 

int main(int argc, char *argv[]) 
{ 
    int first_number = atoi(argv[1]); 
    int second_number = atoi(argv[2]); 

    unsigned int not_equal = (first_number^second_number); 

    while (not_equal & ~0x01) 
     not_equal >>= 1; 

    char *response[2] = { "Numbers Match!\n", 
          "Numbers don't match...\n"}; 

    printf(response[not_equal]); 

    return 0; 
} 
Problemi correlati