2013-10-01 8 views
8

Aus dem Nichts bekomme ich ein ziemlich großes Ergebnis für diese Funktion ... Es sollte sehr einfach sein, aber ich kann es jetzt nicht sehen.Schreckliche Nummer kommt aus dem Nichts

double prob_calculator_t::pimpl_t::B_full_term() const 
{ 
    double result = 0.0; 
    for (uint32_t j=0, j_end=U; j<j_end; j++) 
    { 
     uint32_t inhabited_columns = doc->row_sums[j]; 
     // DEBUG 
     cout << "inhabited_columns: " << inhabited_columns << endl; 
     cout << "log_of_sum[j]: " << log_of_sum[j] << endl; 
     cout << "sum_of_log[j]: " << sum_of_log[j] << endl; 
     // end DEBUG 
     result += (-inhabited_columns * log(log_of_sum[j]) + sum_of_log[ j ]); 
     cout << "result: " << result << endl; 
    } 
    return result; 
} 

und wo ist die Spur:

inhabited_columns: 1 
log_of_sum[j]: 110.56 
sum_of_log[j]: -2.81341 
result: 2.02102e+10 
inhabited_columns: 42 
log_of_sum[j]: 110.56 
sum_of_log[j]: -143.064 
result: 4.04204e+10 

Danke für die Hilfe!

+0

Sind diese für 'j' Werte Null und Eins? Sind Sie sicher, dass "log" "std :: log" ist? – aschepler

+0

Ich stimme den 3 Schlussabstimmungen nicht zu. Die Frage ist gut geschrieben: guter Code, gute Ausgangsspur und die Antwort ist subtil. Und es gibt 5 Upvotes zu der Frage. Würden die engsten Wähler näher erläutern? – Bathsheba

Antwort

14

inhabited_columns ist unsigned und ich sehe eine unäre - kurz bevor es: -inhabited_columns.

(Beachten Sie, dass unary - eine sehr hohe Operatorpriorität hat; höher als * usw.).

Das ist, wo Ihr Problem ist! Um die Antwort von Mike Seymour zu zitieren:

Wenn Sie es negieren, ist das Ergebnis noch nicht signiert; der Wert wird modulo 2 reduziert, um einen großen positiven Wert zu geben.

One fix wäre

-(inhabited_columns * log(log_of_sum[j])) 

dann als die Negation in Gleitkomma durchgeführt wird, schreiben sein

+5

Und zu denken, die Antwort war immer richtig, in Ihrem Namen;) – SvenS

+0

Dies ist typisch für das, was geschieht, wenn Sie die Grundregel verletzen: Der Standardtyp für numerische Werte ist 'int'. Verwenden Sie niemals einen vorzeichenlosen Typ für einen numerischen Wert. Wenn Sie alle "uint32_t" durch "int" ersetzen, wäre der Code korrekt. –

+0

Guter Rat James. Vielleicht hat Java deshalb auch nicht signierte Typen gelöscht? – Bathsheba

6

inhabited_columns ist ein Typ ohne Vorzeichen. Wenn Sie es negieren, ist das Ergebnis immer noch nicht signiert. der Wert wird modulo 2 reduziert, um einen großen positiven Wert zu geben.

Sie sollten es in einen ausreichend großen signierten Typ (vielleicht int32_t, wenn Sie nicht mehr als ein paar Milliarden Spalten haben), oder vielleicht double ändern, da Sie es in doppelter Genauigkeit verwenden werden Arithmetik.

Verwandte Themen