Meine Vermutung ist, dass dies einfach eine Zufallszahl aus einer Gleichverteilung erzeugt auf dem Intervall [0,1]; ist das richtig?
Nr. Code kann nie 1.0f
noch einheitliche Ergebnisse zurückgeben.
#define random ((float) rand()/(float)((1 << 31) - 1))
hat viele Probleme. Es ist ein schwacher Code.
verloren Präzision: Typische float
hat etwa 24-Bit-Präzision. Konvertiert man das Ergebnis von rand()
, wenn es 24 Bits überschreitet, ergibt sich eine float
, die sich aufgrund von Rundungen vom Originalwert unterscheiden kann. Dies schwächt/zerstört die Einheitlichkeit der Zufallszahlengenerierung. Verschiedene rand()
Ergebnisse werden mit der gleichen Antwort kommen. Siehe auch @Olaf
Eine Lösung für dies ist problematisch, da OP offenbar eine einheitliche Zufallszahl aus dem Satz will [0, 1/2147483648, 2/2147483648 ... 2147483647/2147483648], die die wahrscheinliche Genauigkeit gegeben ist nicht möglich Grenzen von float
.
Das Schlimmste ist, dass (1 << 31)
undefinierten Verhalten UB ist, es sei denn int
lang mindestens 33 Bits. Eine 1 in die Vorzeichenposition zu schieben ist UB. C11dr §6.5.7 4.
Um UB zu vermeiden, verwenden Sie ((1ul << 31) - 1)
.
Noch ist die Verwendung der magischen Zahl ((1ul << 31) - 1)
nicht so robust wie das Basieren der Fraktion auf RAND_MAX
.
Weitere (float) ((1ul << 31) - 1)
kann unter Verlust der Genauigkeit leiden, wie oben beschrieben, da es den Wert 2147483648.0f
und nicht das nicht erhältliche 2147483647.0f
bildet. OP-Code kann nie ein 1.0f
erzeugen.
Ich vermute, OP benötigt wirklich ein [0..1) Ergebnis und nicht [0..1]. Beide sind unten.
// generate a `double` in the range [0 ... 1)
#define random0to_almost1 (rand()/(RAND_MAX + 1.0))
// or
// generate a `double` in the range [0 ... 1]
#define random0to1 (rand()/(RAND_MAX + 0.0))
Beachten Sie, dass dies wie Original-Code des OP leidet, sollte die Genauigkeit der double
(typisch 53 Bit) durch RAND_MAX
Bedürfnisse überschritten.
Um zu bewältigen, ist ein mildernder Schritt zu versichern, RAND_MAX + 1.0
ist genau getan. In der extrem gebräuchlichen, aber nicht C angegeben, ist RAND_MAX
eine Power-of-2_minus_1. So RAND_MAX/2 + 1
ist ein int
und ein genaue Leistung von 2. Die Umwandlung von int
zu double
ist sicherlich genau.
#define random0to_almost1 (rand()/(2.0*(RAND_MAX/2 + 1)))
A float
Lösung
// This value is platform dependent, but very common
// Do not a a highly portable generation method yet.
#define FLT_POWER2_INTEGER_LIMIT (1ul << 24)
#define random0to_almost1 (\
(rand() % FLT_POWER2_INTEGER_LIMIT)/\
(RAND_MAX % FLT_POWER2_INTEGER_LIMIT + 1.0f) \
)
undefiniertes Verhalten auf allen Plattformen mit 'int' mit nicht mehr als 32 Bits) sein würde. Alles kann passieren, Fall geschlossen - nächste bitte! – Olaf
Mögliches Duplikat von [Ist 1 << 31 in C gut definiert, wenn sizeof (int) == 4] (https://stackoverflow.com/questions/45268467/is-131- well-defined-in-c-when- sizeofint-4) –