Самый быстрый способ перевернуть знак double / float в C
каков самый быстрый способ перевернуть знак двойника (или поплавка) в C?
Я подумал, что доступ к биту знака напрямую будет самым быстрым способом и нашел следующее:
double a = 5.0;
*(__int64*)&a |= 0x8000000000000000;
// a = -5.0
float b = 3.0;
*(int*)&b |= 0x80000000;
// b = -3.0
однако выше не работает для отрицательных чисел:
double a = -5.0;
*(__int64*)&a |= 0x8000000000000000;
// a = -5.0
4 ответов
любой приличный компилятор реализует эту бит-манипуляцию, если вы просто добавляете оператор отрицания, т. е. -a
. В любом случае, ты или ... Вы должны XOR это. Это то, что компиляторы, которые я тестировал, все равно делают (GCC, MSVC, CLang). Так что просто сделайте себе одолжение и писать -a
EDIT: имейте в виду, что C не применяет какой-либо конкретный формат с плавающей запятой, поэтому любые битовые манипуляции с неинтегрированными переменными C в конечном итоге приведут к ошибочным поведение.
редактировать 2 из-за комментария: это код отрицания, который GCC излучает для x86_64
.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
следует отметить, что xorps
XOR конструировано для плавая пунктов, заботясь о специальных условиях. Это инструкция SSE.
этот код не определен, поскольку он нарушает строгое правило сглаживания. что такое строгое правило антиалиасинга? Для этого вам придется полагаться на компилятор, оптимизирующий его для вас.