有符号数和无符号数(你想知道的C语言 3.5)

Q:整数区分出有符号数和无符号数的意义是什么?

A:整数有正数也有负数,有符号数为了在基本数据类型大小之内既表达正负,又表达数值,才不至于在表达正负依赖其他基本类型或复杂类型协助,失去C语言简洁的特性。

      无符号数相当于只有正数,在常规意义数值分析上最大挖掘和表达类型内存空间的范围。

      

Q:浮点数为何没有有符号数和无符号数的称呼?

A: 浮点数一般采用IEEE754 去表达,已有符号位,不需有符号和无符号特别称呼。

 

Q: CPU如何识别有符号和无符号数?

A: 其实CPU根本不识别有符号数和无符号数,它只是当做数。问题来了,代码中有signed和unsigned区别的数,CPU怎么能正确处理?

int i = 1;
unsigned u = 2;

printf("%d %d\n", i, u);
movl	$0x1, %esi
movl	$0x2, %edx

      编译器都是用movl指令,似乎没看到int和unsigned.

int i = -1;
unsigned u = -1;

printf("%d %d\n", i, u);
movl	$0xffffffff, %esi
movl	$0xffffffff, %edx

    编译器把-1转换成0xffffffff, CPU还是不知道int和unsigned是何物,上面的代码编译器确认只有printf使用i和u, 直接填入数值即可。

 

Q: char/unsigned char和int转换的代码可能让CPU迷惑,看看有什么不同。

A: 

int char_to_int(signed char c)
{
	return c;
}

 

pushq	%rbp
movq	%rsp, %rbp
movb	%dil, %al
movb	%al, -0x1(%rbp)
movsbl	-0x1(%rbp), %eax
popq	%rbp
retq

注: g++编译, 默认clang会优化。

      signed char转换成int: movsbl指令会扩展符号位,从char到int.

int uchar_to_int(unsigned char c)
{
	return c;
}

  

pushq	%rbp
movq	%rsp, %rbp
movb	%dil, %al
movb	%al, -0x1(%rbp)
movzbl	-0x1(%rbp), %eax
popq	%rbp
retq

注: g++编译, 默认clang会优化。

    unsigned char转换成int: movzbl指令高位扩展为0(即不扩展符号位),从char到int.

    movsbl和movzbl和有符号数无符号数挂上钩了,虽然也是编译器提供的指令!

 

作者:     陈曦
环境:     MacOS 10.14.5 (Intel i5)
         Apple LLVM version 10.0.1 (clang-1001.0.46.4)
         Target: x86_64-apple-darwin18.6.0
 
         Linux 3.16.83 (Ubuntu)
 
转载请注明出处

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值