JavaScript 数字是如何存储的
在本文中,我们将试着了解JavaScript中的数字是如何存储的。和其他编程语言一样,所有的数据都以二进制数0和1的形式存储在计算机内部。因为计算机只能理解和处理以0和1的形式表示的数据。
在JavaScript中,通常只有一个Number作为原始数据类型,但数字的形式是整数和浮点数。因此,这些类型属于Number数据类型,并根据进行的操作类型不同在内部以不同的格式存储。
现在让我们了解一下JavaScript中不同数字的存储方式。
整数的存储
整数: 这些数字又可分为两种类型。
- 有符号整数
- 无符号整数
为了存储无符号整数,使用简单的二进制格式。
以下是一些示例,展示了不同无符号整数在JavaScript中的存储方式。
let a = 4
let b = 78
a will be stored in the memory with the value of:- 100
b will be stored in the memory with the value of:- 1001110
注意: 当处理无符号整数时,这种方法会失败,因为需要额外的数据来存储数字的符号。
有一个约定,将最左边的位作为符号位,用0表示正数,用1表示负数。
这种方法被称为 有符号数值 。
下面的示例说明了我们将如何以有符号数值格式存储数字。
let a = 6
let b = -6
a will be stored in memory with the value of :- 000110
b will be stored in memory with the value of :- 100110
在尝试对这两个值执行加法时出现了一个问题。对二进制数进行的加法运算返回
100110 + 000110 = 101100 // 44
当我们将这两个数字相加时,应该得到0,但实际上得到了44。
这种方法的进一步改进是使用一的补码表示来存储数字。
一个数的一的补码 是将所有0变为1,将所有1变为0。假设有一个二进制数11001001,那么它的一的补码将是00110110。
现在让我们了解一下如何使用这种方法来存储内存中的数字。
假设二进制格式中的数字为100111,由于1是最左边的位,它将被视为负数。现在它的一的补码是011000,转换为十进制格式是24,因此我们将100111视为-24。
在这种方法中,之前方法中出现的问题部分得到解决,因为现在加法开始给出正确的结果,但还是存在一些异常情况,例如使用这种表示方式相加3和-2时,我们得到错误的输出。
3 -> 000011
-2-> 111101
After addition we get -> 000000 which is +0
输出预期为 1 。
为了进一步提升这种方法,引入了 二进制补码 格式
补码 是一个数字的补码,类似于反码。唯一的区别是,在求得反码后,还要再次将1加到结果上。
上述24( 011000 )的补码为101000。当将此数字与原始数字24相加时,输出为000000,其中进位位被忽略,算术运算成功执行。
24 -> 011000
two's complement of 24 -> 101000
Addition gives -> 1000000
// One is ignored as digits upto 6 bits are counted
所以-24将在存储器中表示为101000
结论:
在存储整数时,遵循无符号位的简单二进制格式
为了储存有符号位整数,数字在内部将以补码形式储存,以增加存储容量和改善算术运算。
浮点数的存储。
为了存储浮点数,我们将其分为三个部分:符号位、指数和尾数。
- 符号位: 用于指示数字的符号,约定为正数时为0,负数时为1。
- 指数: 是实际二进制数与其规范化形式的差值。
- 尾数: 用于存储浮点数规范化形式的小数部分。
使用32位格式表示的浮点数称为单精度,而使用64位格式表示的浮点数称为双精度。
在不同格式下存储数字所需的存储空间:
类型 | 符号 | 指数 | 尾数 |
---|---|---|---|
单精度 | 1位 | 8位 | 23位 |
双精度 | 1位 | 11位 | 52位 |
浮点数表示中使用偏置的概念来表示负数,而不是用一补数和二补数。偏置的使用是因为在使用二补数表示的浮点数中,比较变得困难。
例如,一个普通的6位表示将包含从000000到111111的数字,但IEEE给出了一个公式,可以储存负数。如果n是位数,该公式为。
bias = 2(n-1) - 1
// Here n = 6
therefore bias = 31
这意味着在6位表示中,我们可以存储从-31到32的数字
让我们看看二进制数101.101如何以科学计数法表示。
我们将得到1.01101 * 2^2
- 这里, 符号位 是0,将是最左边的位
- 指数 是2。它将表示原始二进制数与标准化形式之间的距离。
- 尾数 是小数部分,将是01101
存储无理数。
计算机仍然无法存储和处理无理数,因此无法存储。
JavaScript内部如何存储数字:
现在让我们了解JavaScript如何在内部管理存储数字。JavaScript没有单独的整数和浮点数表示格式。它对所有类型的数字使用Numbers。在JavaScript内部,每个数字都存储为64位浮点数。在某些情况下,用于整数算术运算的是二进制补码格式。
JavaScript中浮点数的问题:
- 浮点数不总是准确的,并给出近似结果。
示例: 在这个例子中,我们将尝试理解上述问题。
Javascript
let x = 0.1;
let y = 0.2;
console.log(x+y);
输出: 在这里,为了快速性能而给出了一种近似结果,而不是真正的计算结果。
0.30000000000000004
- 浮点数根据其结合性给出不同的输出
例子: 我们将通过下面给出的例子来理解结合性问题。
Javascript
let x = 0.1;
let y = 0.2;
let z = 0.3
console.log((x+y)+z);
console.log(x+(y+z));
输出: 由于浮点数计算是基于舍入的,因此尽管在实际应用中应该是相同的,但结果并不总是相同的。
0.6000000000000001
0.6