Runden des Ergebnisses der Division auf die nächste ganze Zahl ist pretty simple. Aber ich versuche ein Ergebnis der Division zu runden, damit die nachfolgende Operation die beste Annäherung ergibt. Das ist am besten erklärt durch eine einfache Funktion:Rund y = x * x zum nächsten
const int halfbits = std::numeric_limits<unsigned int>::digits/2;
unsigned x = foo(); // Likely big.
unsigned x_div = x >> halfbits; // Rounded down
unsigned y = x_div * x_div; // Will fit due to division.
I x_div
zum nächsten Runde kann 1<<(halfbits-1)
durch Zugabe. Aber da x² keine lineare Funktion ist, wird y im Allgemeinen nicht richtig gerundet. Gibt es eine einfache und genauere Möglichkeit, (x*x) >> (halfbits*2)
zu berechnen, ohne größere Typen zu verwenden?
Ich denke, dass das Hinzufügen von 3<<(halfbits-3)
zu x_div die Rundung verbessert, kann aber nicht beweisen, dass das die beste Lösung ist. Kann dies auch für xⁿ verallgemeinert werden?
Bearbeiten: auf vielfachen Wunsch erlaube ich mir, die Frage in rein rechnerischen Begriffen "übersetzen" (keine dieser C Bit-Verschiebung Sache ...).
Hinweis: Alle Divisionen danach sind ganzzahlige Divisionen, zum Beispiel 13/3 wäre 4.
Problem: Wir können nicht x^2 berechnen, weil x groß ist, also möchten wir stattdessen berechnen (x^2)/(2^N).
Dazu berechnen wir
x_div = x/sqrt (2^N)
die wir dann Quadrat:
y = x_div * x_div
Dies ist jedoch aufgrund der Regel kurz vor dem exakten Wert von (x^2)/(2^N)
und das OP schlägt vor, 0.5 * sqrt (2^N) oder vielleicht 0.375 * sqrt (2^N) hinzuzufügen, um das Ergebnis besser zu nähern ...
Oli Charlesworth
's Antwort schlägt vor, es gibt eine viel bessere Weise, zum zu gelangen tatsächlicher Wert, indem an x^2
als (x_hi + x_lo)^2 gedacht wird.
Ich bin nicht mit den Bit-Ops verloren, aber könnten Sie vielleicht die Operationen in einer mathematischen zentrischen und weniger c-zentrischen Weise umformulieren? Ich versuche nicht, pedantisch zu sein, ich denke nur, dass es helfen würde, das vorliegende Problem zu klären und dabei zu helfen, Ihr Ziel zu formulieren. –
Mehrere Dinge zu versuchen: 'x_div_down * x_div_up',' x_div_near * x_div_near'. Wenn Sie bereit sind, die Zeit zu verbringen, können Sie '(x_div * x_rest) >> (halfbit-1)' berechnen und das Ergebnis korrigieren. –
Also, nur um klar zu sein, impliziert durch Ihre '(x * x) >> (halfbits * 2)', wollen Sie eigentlich * unrund * bitgenaues Ergebnis davon? Oder möchten Sie, dass das mathematische Ergebnis korrekt gerundet wird? – hyde