c - 8位二进制0减1

标签 c math binary twos-complement integer-arithmetic

我有 8 位 int zero = 0b00000000; 和 8 位 int one = 0b00000001; 根据二元运算法则,

0 - 1 = 1 (borrow 1 from next significant bit).

如果我有:

int s = zero - one; 
s = -1; 
-1 = 0b1111111;

所有这些 1 来自哪里?没有什么可以借用的,因为 zero 变量中的所有位都是 0

最佳答案

这是一个很好的问题,与计算机如何表示整数值有关。

如果您要写出以十为底的负数,您只需写出常规数字,然后在其前面加上减号。但是,如果您在一台计算机中工作,其中所有内容都需要为零或一,则您没有任何减号。接下来的问题是您如何选择表示负值。

一种流行的方法是使用带符号的补码形式。其工作方式是您使用 1 和 0 来编写数字,除了这些 1 和 0 的含义与“标准”二进制的解释方式不同。具体来说,如果您有一个带符号的 8 位数字,则低七位的标准含义为 20、21、22等。但是,最高有效位的含义发生了变化:它不再代表 27,而是代表值 -27

让我们看看数字 0b11111111。这将被解释为

-27 + 26 + 25 + 24 + 23 + 22 + 21 + 20

= -128 + 64 + 32 + 16 + 8 + 4 + 2 + 1

= -1

这就是为什么这个位集合表示 -1。

还有另一种方式来解释这里发生的事情。鉴于我们的整数只有八位可用,我们知道没有办法表示所有可能的整数。如果您选择任意 257 个整数值,假设只有 256 种可能的位模式,则无法唯一地表示所有这些数字。

为了解决这个问题,我们也可以说我们的整数值不代表整数的真实值,而是代表该整数模 256 的值。我们将存储的所有值都介于0 和 255,包括在内。

在那种情况下,0 - 1 是多少?它是 -1,但如果我们将该值 mod 256 强制为非负值,那么我们会得到 -1 = 255 (mod 256)。你会如何用二进制写出 255?是 0b11111111。

如果您有兴趣,这里还有很多其他很酷的东西可以学习,所以我建议您阅读有符号和无符号的补码。

作为一些练习:-4 在这种格式下会是什么样子? -9 怎么样?

这些并不是您在计算机中表示数字的唯一方式,但它们可能是最流行的方式。一些较旧的计算机使用 balanced ternary number system (特别是 Setun 机器)。还有 one's complement format ,这几天不是很流行。

关于c - 8位二进制0减1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46570941/

相关文章:

math - 这里正在做什么? (使用数学识别)

javascript - 写一个函数 "solves"一个方程

javascript - 如何在纯 JavaScript 中发送二进制数据?

linux - 如何设置gdb运行在/bin/sh

c - C哈希表实现中的内存泄漏

c - 线程堆栈指针

c - OpenCV中的矩形矩阵计算

c - 从 ARM 5 迁移到 ARM 6 编译器 : Use of undeclared identifier '__Vectors'

c# - 计算 WPF 或 SVG 图形的坐标点

swift - 在 Swift 中我无法创建二进制负数