Der schnellste Weg, das Vorzeichen eines Double / Float in C umzukehren

Der schnellste Weg, das Vorzeichen eines Double / Float in C umzukehren


Was ist der schnellste Weg, um das Vorzeichen eines Doubles (oder Floats) in C umzukehren?


Ich dachte, dass der direkte Zugriff auf das Vorzeichenbit der schnellste Weg wäre und fand Folgendes:


double a = 5.0;
*(__int64*)&a |= 0x8000000000000000;
// a = -5.0
float b = 3.0;
*(int*)&b |= 0x80000000;
// b = -3.0

Das obige funktioniert jedoch nicht für negative Zahlen:


double a = -5.0;
*(__int64*)&a |= 0x8000000000000000;
// a = -5.0

Antworten:


Jeder anständige Compiler wird diese Bitmanipulation implementieren, wenn Sie einfach einen Negationsoperator voranstellen, z. B. -a . Wie auch immer, Sie OR-ing das Bit. Sie sollten es XOR. Das machen die von mir getesteten Compiler sowieso (GCC, MSVC, CLang). Also tun Sie sich einfach einen Gefallen und schreiben Sie -a


BEARBEITEN:Beachten Sie, dass C kein bestimmtes Fließkommaformat erzwingt, sodass alle Bitmanipulationen an nicht ganzzahligen C-Variablen letztendlich zu fehlerhaftem Verhalten führen.



EDIT 2 aufgrund eines Kommentars :Dies ist der Negationscode, den GCC für x86_64 ausgibt


.globl neg
.type neg, @function
neg:
.LFB4:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
movq %rsp, %rbp
.cfi_offset 6, -16
.cfi_def_cfa_register 6
movss %xmm0, -4(%rbp)
movss -4(%rbp), %xmm1
movss .LC0(%rip), %xmm0
xorps %xmm1, %xmm0 /* <----- Sign flip using XOR */
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE4:
.size neg, .-neg

Zu beachten ist, dass xorps ist XOR, das für Fließkommazahlen entwickelt wurde und besondere Bedingungen berücksichtigt. Es ist eine SSE-Anweisung.