Im Wesentlichen macht es einige binäre Manipulation der Gleitkommadaten, in einer nicht tragbaren Art und Weise: Es gibt klare Annahmen über die relativen Größen von int
und float
und auch über ihre Darstellung. Ich denke, dass , wennint
ist eine 32-Bit 2'-Komplement Integer und float
ist ein IEEE 32-Bit Gleitkommawert, dann können Sie die Gleitkommawerte nur mit ganzzahligen Operationen vergleichen.
mehr Details ...
int* ivalues = (int*)values;
Dies gibt uns nur einen Zeiger, der durch die Fließkommawerte zu Fuß verwendet wird. Sie sind interpretiert als ints
, nicht umgewandelt zu int
- mit anderen Worten: es gibt keinen Grund zu denken, dass ein float
mit einem Wert von 1.0
zu einem int
Wert von 1
abbildet. Das Wichtigste, was Sie tun können, sind bitweise Operationen oder spezifische Manipulationen, die darauf angewiesen sind, das für float
verwendete Binärformat zu verstehen.
auf der Makro-Blick ...
#define CV_TOGGLE_FLT(x) ((x)^((int)(x) < 0 ? 0x7fffffff : 0))
Der Wert x
(denken Sie daran, nur einige der Bits, die sonst einen Fließkommawert darstellen, aber hier sehen wir nur an sie als Bitmuster) ist XOR-ed mit entweder 0
(die keine Wirkung hat) oder 0x7fffffff
(die die niederwertigen 31 Bits invertiert). Die Entscheidung, was zu tun ist, basiert darauf, ob x
kleiner als Null ist oder nicht.
Ich denke, dieses Makro basiert auf der Annahme, dass eine int
eine 32-Bit-2's-Komplement-Darstellung ist. Das bedeutet, dass x < 0
wahr ist, wenn das oberste Bit gesetzt ist. Das XOR mit 0x7fffffff
wird die anderen Bits invertieren. Dies bedeutet, dass -1
, die positivste negative Zahl, von 0xffffffff
zu 0x8000000
geändert wird. Dies ist die negativste negative Zahl (-2147483648
) und ebenfalls 0x8000000
wird 0xffffffff
. Wenn Sie danach >
verwenden, um zwei negative Zahlen zu vergleichen, bedeutet das, dass die negativere Nummer nun die positivere Nummer ist, und die "größer als" Verzweigung wird genommen. Vergleicht man zwei positive Zahlen unverändert, vergleicht man eine positive Zahl mit einer negativen Zahl, ist die positive Zahl erwartungsgemäß immer noch größer.
Damit können Sie Vergleiche für float
s mit nur ganzzahligen Operationen durchführen. Dies liegt daran, dass die Art und Weise, wie float
s im IEEE-Format negative Zahlen speichern, sich deutlich von dem Zweierkomplement unterscheidet: Das Vorzeichenbit ist wirklich nur ein Flag, dass der Wert positiv oder negativ ist, und die restlichen Bits speichern die Größe der Zahl. Sobald Sie die CV_TOGGLE_FLT(x)
angewendet haben, haben Sie keine Werte, die Sie direkt verwenden können, aber sie sind auf die gleiche Weise wie die ursprünglichen float
Werte sortiert.
extrahiert nur Ints aus Float in einem bestimmten Format. Es ist schwer, mehr zu sagen, da mehr Code analysiert werden muss, als Sie zur Verfügung gestellt haben. Bitte überprüfen Sie diesen Link, vielleicht wird es für Sie klarer, wenn Sie das Float-Format überprüfen. https://en.wikipedia.org/wiki/Single-precision_floating-point_format – nosbor