区分负数和正数?
Differentiate between negative and positive numbers?
在二进制中我们可以有一个有符号数和一个无符号数,假设我们得到一个值 0101
我们如何判断它等于 5
还是等于 -1
as you may notice the second bit from the left is on
二进制没有区别。区别在于给定的语言/编译器/环境/处理器如何处理给定的二进制数字序列。例如,在 Intel x86/x64 世界中,您有 MUL
和 IMUL
乘法指令。 IMUL
指令执行 signed 乘法(即将操作数位视为有符号值)。还有其他一些指令区分signed/unsigned操作数(例如DIV
/IDIV
、MOVSX
等)。
这是一个简单的例子:
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
int main(void)
{
int16_t c16;
uint16_t u16;
__asm {
mov al, 0x01
mov bl, 0x8F
mul bl // ax = 0x01 * 0x8F
mov u16, ax
mov al, 0x01
mov bl, 0x8F
imul bl // ax = 0x01 * 0x8F
mov c16, ax
};
char uBits[65];
char cBits[65];
printf("%u:\t%s\n", u16, _itoa(u16, uBits, 2));
printf("%d:\t%s\n", c16, _itoa(c16, cBits, 2));
return 0;
}
输出为:
143: 10001111
-113: 11111111111111111111111110001111
编辑时:
只是为了扩展示例 - 在 C/C++ 中(与其他区分有符号和无符号数量的语言一样),编译器知道它是在有符号值还是无符号值上运行并生成适当的指令。在上面的示例中,编译器还知道它必须在调用 _itoa()
时正确地对变量 c16
进行符号扩展,因为它将它提升为 int
(在 C/C++ 中, int
是默认签名的——相当于说 signed int
)。在对 _itoa()
的调用中,变量 u16
被提升为 unsigned int
,因此不会发生符号扩展(因为在无符号值中显然没有符号位这样的东西)。
在实际硬件上,负数的实现取决于设计者的选择。通常有符号数用 Two's Complement
表示
但是还有Many More
在二进制中我们可以有一个有符号数和一个无符号数,假设我们得到一个值 0101
我们如何判断它等于 5
还是等于 -1
as you may notice the second bit from the left is on
二进制没有区别。区别在于给定的语言/编译器/环境/处理器如何处理给定的二进制数字序列。例如,在 Intel x86/x64 世界中,您有 MUL
和 IMUL
乘法指令。 IMUL
指令执行 signed 乘法(即将操作数位视为有符号值)。还有其他一些指令区分signed/unsigned操作数(例如DIV
/IDIV
、MOVSX
等)。
这是一个简单的例子:
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
int main(void)
{
int16_t c16;
uint16_t u16;
__asm {
mov al, 0x01
mov bl, 0x8F
mul bl // ax = 0x01 * 0x8F
mov u16, ax
mov al, 0x01
mov bl, 0x8F
imul bl // ax = 0x01 * 0x8F
mov c16, ax
};
char uBits[65];
char cBits[65];
printf("%u:\t%s\n", u16, _itoa(u16, uBits, 2));
printf("%d:\t%s\n", c16, _itoa(c16, cBits, 2));
return 0;
}
输出为:
143: 10001111
-113: 11111111111111111111111110001111
编辑时:
只是为了扩展示例 - 在 C/C++ 中(与其他区分有符号和无符号数量的语言一样),编译器知道它是在有符号值还是无符号值上运行并生成适当的指令。在上面的示例中,编译器还知道它必须在调用 _itoa()
时正确地对变量 c16
进行符号扩展,因为它将它提升为 int
(在 C/C++ 中, int
是默认签名的——相当于说 signed int
)。在对 _itoa()
的调用中,变量 u16
被提升为 unsigned int
,因此不会发生符号扩展(因为在无符号值中显然没有符号位这样的东西)。
在实际硬件上,负数的实现取决于设计者的选择。通常有符号数用 Two's Complement
表示但是还有Many More