Dies ist wahrscheinlich eine Frage für einen x86-FPU Experten:Punkt Rundung treiben, wenn
Ich versuche, eine Funktion zu schreiben, die einen zufälligen Fließkommawert im Bereich [min, max] erzeugt. Das Problem ist, dass mein Generatoralgorithmus (der Gleitkomma-Mersenne-Twister, wenn Sie neugierig sind) nur Werte im Bereich [1,2] zurückgibt - dh ich möchte eine inklusive obere Schranke, aber meinen "source" -Erzeugungswert ist aus einer exklusiven oberen Grenze. Der Catch hier ist, dass der zugrunde liegende Generator ein 8-Byte-Double zurückgibt, aber ich möchte nur ein 4-Byte-Float, und ich verwende den Standard-FPU-Rundungsmodus von Nearest. Ich möchte wissen, ob die Kürzung selbst in diesem Fall dazu führt, dass mein Rückgabewert Max enthält, wenn der FPU interne 80-Bit-Wert ausreichend nahe ist, oder ob ich den Signifikanden meines Max-Wertes erhöhen sollte vor der Multiplikation mit dem intermediären Random in [1,2], oder ob ich FPU-Modi ändern sollte. Oder irgendwelche anderen Ideen, natürlich.
Hier ist der Code, den ich zur Zeit benutzen, und ich habe überprüfen, ob 1.0f beschließt zu 0x3f800000:
float MersenneFloat(float min, float max)
{
//genrand returns a double in [1,2)
const float random = (float)genrand_close1_open2();
//return in desired range
return min + (random - 1.0f) * (max - min);
}
Wenn es einen Unterschied macht, muss diese sowohl auf Win32 MSVC++ und Linux gcc arbeiten. Wird die Verwendung von Versionen der SSE-Optimierungen die Antwort ändern?
Edit: Die Antwort ist ja, Trunkierung in diesem Fall von Doppel auf Float ist ausreichend, um das Ergebnis einschließlich von max zu verursachen. Weitere Informationen finden Sie in der Antwort von Crashworks.
Nun, warum habe ich nicht daran gedacht, diesen Test unter den anderen auszuführen? Ich habe herausgefunden, dass der 1.99999 mit truncation auf 2 mit und ohne/arch: SSE2 aufrundet. Vielen Dank! –
Ich bin froh zu helfen - ich war neugierig, was das Ergebnis des Tests wäre ich selbst. – Crashworks