gpt4 book ai didi

c - 获取整数的负号并将其存储为 char 的最佳方法是什么?

转载 作者:行者123 更新时间:2023-12-04 10:45:23 26 4
gpt4 key购买 nike

如何获取整数的符号并将其存储在字符中?一种方法是:

int n = -5
char c;
if(n<0)
c = '-';
else
c = '+';

或者:

char c = n < 0 ? '-' : '+';

但是有没有办法不用条件判断呢?

最佳答案

有最高效、最便携的方式,但它没有赢得任何美容大奖。

我们可以假设,如果有符号整数的 MSB 为负,则它总是被设置。这是一个 100% 可移植的假设,即使考虑到奇异的符号格式(一个人的补码,有符号的幅度)也是如此。因此,最快的方法是简单地从整数中屏蔽掉 MSB。

任何整数的 MSB 位于 CHAR_BIT * sizeof(n) - 1; 位置.在典型的 32 位主流系统上,这例如是 8 * 4 - 1 = 31.

所以我们可以这样写一个函数:

_Bool is_signed (int n)
{
const unsigned int sign_bit_n = CHAR_BIT * sizeof(n) - 1;
return (_Bool) ((unsigned int)n >> sign_bit_n);
}

在 x86-64 gcc 9.1 (-O3) 上,这会产生非常高效的代码:

is_signed:
mov eax, edi
shr eax, 31
ret

这种方法的优点还在于,不像x < 0这样的代码,在移植时它不会冒被翻译成“如果否定则分支”指令的风险。

完整示例:

#include <limits.h>
#include <stdio.h>

_Bool is_signed (int n)
{
const unsigned int sign_bit_n = CHAR_BIT * sizeof(n) - 1;
return (_Bool) ((unsigned int)n >> sign_bit_n);
}

int main (void)
{
int n = -1;

const char SIGNS[] = {' ', '-'};
char sign = SIGNS[is_signed(n)];
putchar(sign);
}

反汇编(x86-64 gcc 9.1 (-O3)):

is_signed:
mov eax, edi
shr eax, 31
ret
main:
sub rsp, 8
mov rsi, QWORD PTR stdout[rip]
mov edi, 45
call _IO_putc
xor eax, eax
add rsp, 8
ret

关于c - 获取整数的负号并将其存储为 char 的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56663408/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com