2016-07-24 27 views
2

Ich löste Quasi-Binary Problem (spielt keine Rolle) auf Codeforces und das ist meine submission. Dies ist der Code, den ich produziert haben:Code produziert verschiedene Ausgabe auf verschiedenen Compilern

#include <iostream> 
#include <cmath> 

using namespace std; 

int quasi_binary(int num, int tens) 
{ 
    int res,digit; 

    if(num == 0) 
    { 
     return 0; 
    } 

    digit = num%10; 
    num = num/10; 

    res = quasi_binary(num, tens+1); 

    if(digit) 
    { 
     cout << 1; 
     return ((digit-1)*pow(10,tens)+res); 
    } 
    else 
    { 
     cout << 0; 
     return res; 
    } 
} 

int main() 
{ 
    int n,k=-1,temp,digit; 
    cin >> n; 

    //this loop calculates the value of k,as it needs to be printed first 
    temp=n; 
    while(temp) 
    { 
     digit = temp%10; 
     temp = temp/10; 

     if(digit>k) 
      k=digit; 
    } 
    cout << k << endl; 

    //print those k quasi-numbers 
    while(n) 
    { 
     n = quasi_binary(n,0); 
     cout << " "; 
    } 
    return 0; 
} 

Ich sehe keine Aussage, die nicht definiertes Verhalten auf verschiedenen Compilern produzieren kann. Ich habe auch richtige Klammern an den richtigen Stellen verwendet, um Zweideutigkeiten zu vermeiden. Immer noch undefiniertes Verhalten. Kann jemand bitte helfen, die Anweisung/Anweisung zu finden, die das undefinierte Verhalten erzeugt.

Eingang

415 

Ausgang (online Richter) - falsche

5 
111 101 101 11 11 11 11 11 11 11 11 11 

Output (auf meinem 64-Bit-PC mit gcc) - korrekte

5 
111 101 101 101 1 
+2

'pow (10, Zehner)' - Verwenden Sie keine 'pow' wenn Sie Integer-Exponenten haben. Es gibt [keine Garantie, dass pow Ihnen die richtigen Ergebnisse liefert] (http://stackoverflow.com/questions/25678481/why-pown-2-return-24-whenn-n-5/25678721#25678721). – PaulMcKenzie

+1

Ich glaube nicht, dass es mit Architektur oder Compilern zu tun hat. Verwenden Sie die vollständige Bedingung beim Testen, wenn eine Zahl größer als Null ist. I.e. Verwenden Sie 'if (num> 0)' anstelle von 'if (num) '. Nicht sicher, ob das das Problem ist – smac89

+1

* Ich sehe keine Aussage, die undefiniertes Verhalten auf verschiedenen compilers produzieren kann * - Aber Sie haben Aussagen, die Fließkommawerte ('pow()') produzieren, also ist Ihr Programm nicht garantiert die gleichen Ergebnisse zu erzielen. – PaulMcKenzie

Antwort

5

Um ein Abrunden auf 1 weniger als das mathematische Ergebnis zu vermeiden, ersetzen Sie pow(10, tens) durch int(0.5 + pow(10, tens)).


Oder schreiben Sie Ihre eigene ganzzahlige Potenzfunktion.

z.

using Int_noneg = int;  // "Not negative" 

auto int_pow(Int_noneg const x, Int_noneg const exponent) 
    -> int 
{ 
    Int_noneg reverse_bits = 0; 
    Int_noneg n_exponent_bits = 0; 
    for(Int_noneg i = exponent; i != 0; i /= 2) 
    { 
     reverse_bits = 2*reverse_bits + i%2; 
     ++n_exponent_bits; 
    } 

    Int_noneg result = 1; 
    for(Int_noneg i = 0; i < n_exponent_bits; ++i, reverse_bits /= 2) 
    { 
     result *= result; 
     if(reverse_bits % 2 != 0) { result *= x; } 
    } 
    return result; 
}; 
0

Vor meiner Lösung gehen in, nahm ich für das Team und gingen Sie in Ihrem Beitrag verwiesen auf die Website (nicht brauchen, dies zu tun). Ich habe Ihren von Ihnen geposteten Originalcode eingereicht und Sie erhalten den Fehler. Daher verursacht die pow-Funktion in dem SO-Kommentar, mit dem ich im Hauptkommentarabschnitt verlinkt bin, in der Tat Probleme aufgrund von Gleitkomma- und Trunkierungsproblemen.

Um dies zu umgehen, gibt es ein paar Dinge, die Sie tun können, meist in den anderen Antwort (en) gegeben. Aber ich werde meine Lösung geben:

unsigned long powTable[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 
          10000000, 100000000, 1000000000 }; 

//... 
return ((digit-1)*powTable[tens]+res); 

Anstatt die pow Funktion aufrufen, eine einfache Lookup-Tabelle mit den Kräften von 10 erklärt wird, und dann wird der tens als Index in der Tabelle verwendet.

Live Example

+0

Uhm, ich sehe nicht, dass das eine Verbesserung gegenüber 'int (0.5 + pow (10, tens))' ist, entweder für nur einmal benötigten Code oder (insbesondere) als allgemeineren wiederverwendbaren Code? –

+0

Dies ist eine alternative Lösung, die nicht "pow", sondern eine Nachschlagetabelle verwendet. Niemals behauptet, es sei "besser", nur eine Alternative. – PaulMcKenzie

Verwandte Themen