翻转双/浮在C标志最快的方法 [英] Fastest way to flip the sign of a double / float in C

查看:112
本文介绍了翻转双/浮在C标志最快的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

什么是C到翻盖双的符号(或浮动)的最快方法?

我想,这直接访问符号位将是最快的方式,发现如下:

 双A = 5.0;
*(__ *的Int64)及A | = 0x8000000000000000;
// A = -5.0浮动B = 3.0;
*为(int *)和b | = 0x80000000的;
// B = -3.0

但是,上面并没有为负数工作:

 双A = -5.0;
*(__ *的Int64)及A | = 0x8000000000000000;
// A = -5.0


解决方案

任何像样的编译器将实现此位操作,如果你只是prePEND否定运营商,即 -a 。不管怎样,你的OR-ing位。你应该XOR它。这是我测试的编译器做它无论如何(海合会,MSVC,锵)。所以只是请你帮个忙,写 -a

编辑:请注意,C不执行任何特定的浮点格式,所以非整C变量的位操作,​​最终会造成errornous行为


编辑2由于注释:这是否定code GCC发出了x86_64的

  .globl负
    .TYPE负,@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 / * LT; -----注册翻转使用XOR * /
    离开
    .cfi_def_cfa 7,8
    RET
    .cfi_endproc
.LFE4:
    .size负。-NEG

应当指出的是 xorps 是异或设计用于莲花灯点,采取的特殊条件照顾。这是一个SSE指令。

What is the fastest way to flip the sign of a double (or float) in C?

I thought, that accessing the sign bit directly would be the fastest way and found the following:

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

float b = 3.0;
*(int*)&b |= 0x80000000;
// b = -3.0

However, the above does not work for negative numbers:

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

解决方案

Any decent compiler will implement this bit manipulation if you just prepend a negation operator, i.e. -a. Anyway, you're OR-ing the bit. You should XOR it. This is what the compilers I tested it do anyway (GCC, MSVC, CLang). So just do yourself a favour and write -a

EDIT: Be aware that C doesn't enforce any specific floating point format, so any bit manipulations on non-integral C variables will eventually result in errornous behaviour.


EDIT 2 due to a comment: This is the negation code GCC emits for 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

It should be noted that xorps is XOR designed for floatin points, taking care of special conditions. It's a SSE instruction.

这篇关于翻转双/浮在C标志最快的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆