JavaRush /Java 博客 /Random-ZH /计算机内存中的实数。解释。
Marianna
第 9 级
Москва

计算机内存中的实数。解释。

已在 Random-ZH 群组中发布
下午好 在学习第一个任务的讲座“使用实数的细微差别”(第 2 节:浮点数的结构)以及有关该主题的其他讲座时,许多人一定遇到了有关该主题的许多问题。最初,我试图给自己提供必要的答案,现在我将它们提供给您,以帮助您以一致的逻辑顺序充分理解。 1. 十进制和二进制数字系统。 1.1十进制数字系统是最常见的系统之一;它是我们在学校、大学和生活中用于任何非计算机数学计算的系统。它使用数字1、2、3、4、5、6、7、8、9、0(阿拉伯语) - 总共 10 位数字。数字还有罗马符号,但现在实际上已不使用。在十进制中,计数是以个位、十、百、千、万、数十万、百万等为单位进行计数的。- 换句话说,这些都是数字的数字。 数字的位数是该数字在数字记录中的位置(位置)。自然数的最低位(也是最低有效位)是个位数(最右边)。为什么他是最微不足道的?因为通过删除数字的个位数,数字本身的变化最小(例如,数字 345 和 340)。接下来,第二位数字是十位数字,依此类推。这是什么意思呢?让我们将十进制中的任何整数分解为数字3297 = 3*1000 + 2*100 + 9*10 + 7 因此,我们发现数字3297包含3 个单位的第四位数字(即 3 千)、2 个单位的第三位数字(即 2 百)、9第二位数字的单位(9 个十)和第一位数字的 7 个单位。也就是说,这个数字是三千二百九十七,因此,它是有位置的小数(实数)的数字又如何呢?小数的位数(其小数部分)称为:十分之几、 百分之一、千分之几、万分之一等。该数字距离小数点越远(距离数字的整个部分),其重要性就越低(丢弃它,数字的值变化不大)。例如,我们将任何小数表示为小数: 25.076 = 2*10 + 5 +0*0.1 + 7*0.01 +6*0.001 因此,我们发现小数25.076包含 2 个十、5 个个位、0 个十分之一,百分之七又千分之六。 十进制系统使用 10 位数字和 10 位的倍数 - 因此称为“十进制”。 1.2二进制数字系统是几乎所有现代计算机和其他计算电子设备中使用的数字系统。为了记录数字,它仅使用两位数字 - 0 和 1。 为了不混淆数字所写的数字系统,它在右下角提供了一个指示器(它是数字系统的基数),用于示例: 1000₁₀ 10002 这里第一个数字是十进制中常见的千位,最后一个是二进制表示的数字,在十进制中它是相等的... 8!与十进制系统一样,二进制系统也将数字分解为数字。二进制数中的每个数字称为一位(或数字)。(如果有人感兴趣的话,4 位是一个半字节(或四分体),8 位是一个字节,16 位是一个字,32 位是一个双字)。 位(数字)也从零开始从右到左编号(与十进制系统不同)。最低有效位、最低有效位、右位的序列号为0。接下来是第一位第二位等等,位越老,它的意义就越大(与我们理解的十进制系统类比 - 如果你从数字 1455 中删除那些,你将剩下数字 1450 - 几乎等于初始值。但是如果去掉百位,你将剩下数字 1050,这已经离初始值很远了,因为百位比个位重要得多(高位) )。 例子。 请勿阅读:))) 计算机内存中的实数。 正在开发中!!! - 2 在底部,这个小数二进制数的位用红色编号 - 这个数字总共有 18 位(数字)。展望未来,我想指出,小数以完全不同的方式存储在计算机内存中- 这将在稍后讨论。同时,让我们学习如何将数字从一种数字系统转换为另一种数字系统。 2. 将整数和分数从十进制转换为二进制系统,反之亦然。 2.1 十进制到二进制的转换。 2.1.1 整数。 为了将整数十进制数转换为二进制数系统,您需要将该数字除以 2,记下除法的余数(它始终等于 0 或 1,具体取决于该数字是偶数还是奇数) ,然后将除法的结果再次除以 2 ,再次记下除法的余数(0 或 1),并将第二次除法的结果再次除以 2。如此下去,直到除法的结果等于 1。接下来,我们从最近的除法结果开始,以 相反的顺序写下所有结果的 0 和 1 ,该结果始终等于 1。重要说明。任何整数连续除以 2 的最终结果始终是一 (1)!如果结果大于 1,我们继续将该结果除以 2,直到得到结果 1。除以 2 的结果仅在一种情况下可以为零 (0) - 这是零本身除以 2。 示例。让我们将数字145从十进制转换为二进制。 145/2 = 72(余数1) 72/2 = 36(余数0) 36/2 = 18(余数0) 18/2 = 9(余数0) 9/2 = 4(余数1) 4/2 = 2 (余数0 ) 2/2 = 1 (余数0 ) 现在我们以相反的顺序“收集”二进制数。我们得到号码10010001。完成! 有趣的细微差别 1.让我们将数字 1从十进制转换为二进制。在二进制中,这个数字也会写成1。毕竟除以2的最终结果应该等于1,已经等于数字1本身了。1₁₀ = 12有趣的细微差别2.让我们转换一下数字0从十进制转为二进制。在二进制系统中,该数字也将写为 0。0₁₀ = 02 2.1.2 小数。 如何将小数转换为二进制?要将十进制分数转换为二进制系统,您必须: a)根据第 2.1.1 段中研究的算法 将分数的整个部分转换为二进制系统b)将分数的小数部分乘以2 ,写成结果小数点之前的位数 (总是等于0或1,这是合乎逻辑的),然后只将所得结果的小数部分再次乘以2,在小数点(0或1)之前记下结果的结果数字,依此类推,直到小数部分乘法结果的一部分变为等于 0 或直到所需的小数位数(所需的精度)(等于乘法次数 2)。然后,您需要在分隔实数(小数)数的整数部分和小数部分的 点之后按顺序写下所写的零和一的结果序列。示例 1. 让我们将数字2.25(2 点 25 分之一)从十进制转换为二进制。在二进制系统中,分数将等于10.01。我们是怎么得到这个的?该数字由整数部分(最多一个点)(即 2)和小数部分(即 0.25)组成。 1) 整个部分的平移: 2/2 = 1(余数0) 整个部分将为102)小数部分的翻译。 0.25 * 2 = 0 .5 (0) 0.5 * 2 = 1 .0 (1) 连续乘以 2 后,小数部分变为 0。我们停止相乘。现在我们按顺序“收集”小数部分 - 我们在二进制系统中 得到0.01 。3)将整数和小数部分相加 - 我们得到小数部分2.25将等于二进制分数10.01示例 2. 让我们将数字0.116从十进制转换为二进制。0.116 * 2 = 0.232 (0) 0.232 * 2 = 0.464 (0) 0.464 * 2 = 0.928 (0) 0.928 * 2 = 1.856 (1) //丢弃该结果的整数部分 0.856 * 2 = 1 .712 (1 ) //丢弃该结果的全部部分 0.712 * 2 = 1 .424 (1) //丢弃该结果的全部部分 0.424 * 2 = 0 .848 (0) 正如我们所见,乘法不断进行,结果的小数部分不等于 0。然后我们决定将小数部分转换为二进制,精度为小数点后7 位(位) 。让我们记住我们对无关紧要位的研究——位(bit)距离整体部分越远,我们就越容易忽略它(讲座第1节中有解释,谁忘记了)。我们得到二进制小数0.0001110,点后精度为 7 位。 2.2 二进制到十进制的转换。 2.2.1 整数。 来翻译一下全文一个数从二进制转为十进制,需要将这个数分成几位(位),并将每一位(位)乘以数字2到一定的度数(这个度数从最低有效位开始从右向左计数)(右位)并从 0 开始)。换句话说,二的幂等于给定位的数量(但是这个不成文的规则只能在转换整数的情况下使用,因为对于小数,位的编号从小数部分开始,这被翻译为以不同的方式转换为十进制)。接下来您需要将结果 相加。例子。 让我们将二进制数110011转换为十进制数。 1100112 = 1*2⁵ + 1*2⁴ + 0*23 + 0*22 + 1*21 + 1*2º = 32 +16 +0 + 0 + 2 + 1 = 51₁₀ 结果,我们得到数字 51 二进制系统。有关信息,下面是数字 2 的一次幂的表格请勿阅读:))) 计算机内存中的实数。 正在开发中!!! - 5 请注意,数字的零次方始终为 1。 2.2.2 小数。 为了将二进制小数(实数)转换为十进制,您必须: a)根据第 2.2.1 段中的算法将其整数部分转换为十进制; b)将其小数部分翻译如下。有必要将小数部分表示为数字乘以 2 的乘积之和,并乘以某个负幂(该点之后的第一个数字的幂(在分数的整个部分之后)将等于 -1,对于小数点后的第二位数字将等于 -2 等。)结果该金额将是十进制数字的小数部分。 例子。 让我们将数字10111.01转换为二进制系统。 10111.012 = (1*2⁴ + 0*23 + 0*22 + 1*21 + 1*2°) 。(0*2ˉ1 + 1*2ˉ2) = (16 + 0 + 4 + 2 + 1) 。(0 + 0.25) = 23.25₁₀ 因此,我们得到十进制数23.25 。2 的一次负幂表如下。 2.2.3 将数字从二进制转换为十进制的一般公式。 让我们给出一个将数字从二进制转换为十进制(整数部分和小数部分)的通用公式。 其中A是二进制数系统中的数字; 数制的基数是2(意味着每一位都乘以2的次方); n请勿阅读:))) 计算机内存中的实数。 正在开发中!!! - 7 请勿阅读:))) 计算机内存中的实数。 正在开发中!!! - 4整数位数(位)m是数字 的小数位数(位数)。 从分界点开始的整数部分的第一位以红色突出显示。它始终乘以 2 的零次方。它前面的下一位(左边)乘以 2 的一次方,依此类推。 分界点小数部分的第一位以绿色突出显示。它总是乘以 2 的负一次方。右边的下一位乘以 2 的负二次方,依此类推。 3. 科学记数法:两个系统中的标准化记数法。尾数、指数、指数的次数。 3.1 数字的指数形式。之前,我们研究了按数字记录位置编号 的详细方案。我们以数字0.0000000000000000000016为例。它有一个很长的标准形式条目。在指数形式中,它看起来像这样: 1.6 * 10ˉ²1 那么什么是数字的指数形式以及如何以这种形式表示数字? 数字的科学计数法是将实数表示为尾数指数。方便表示非常大和非常小的数字,以及统一它们的书写。 N = M * pⁿ 其中N是要写入的数字, M是数字的 尾数, p是 基数(等于给定数字的数系的基数), n(整数)是(度) ,可以是正数和负数), p 的 n 次方是特征数(指数,即底数的幂(阶数))。 一个重要的细微差别。如果小数的整数部分不等于 0,则指数的阶次(次数)将为,如果整数部分等于 0,则指数的次数将为3.2 书写数字的正常和标准化形式。 数字的标准形式是尾数(不考虑符号)位于半区间 [0,1] 上的形式,即 0 <= M < 1。这种书写形式有缺点:有些数字写得不明确(例如,0.0001可以写成0.000001*10²、0.00001⋅101、0.0001⋅10º、0.001⋅10ˉ1等)。因此,另一种记录形式广泛存在(尤其是在计算机科学中)——归一化,其中十进制数的尾数取值从1(含)到10(不含),即1 <= M < 10(同样,二进制数的尾数取值从1到2)。换句话说,十进制中的尾数必须是从 1.0(含)到 10(不含)的小数,即 尾数的整数部分必须包含单个数字,小数部分不受数学限制。 标准化形式的优点是,任何数字(0 除外)都以唯一的方式写入。缺点是无法用这种形式表示 0,因此计算机科学中数字的表示为数字 0 提供了一个特殊的符号(位)。 3.3 以指数归一化形式 书写十进制数的示例。 让我们看一下例子。示例 1. 让我们以指数归一化形式写出十进制数1015000(一百万五千)。该数字的数字系统是十进制,因此基数10。让我们选择尾数。为此,请将数字想象为一个分数,其小数部分将等于零(因为该数字是整数):1000000.0。如果数字的整数部分大于0,则将该点向其初始位置(整数部分内)的左侧移动,直到整数部分中只剩下一位数字。在它后面我们加了一个句号。我们丢弃无关紧要的零(在数字末尾)。我们得到的数字的尾数等于1.015。让我们确定该数字的底数的阶数(阶数) 。分隔整数部分和小数部分的点向左移动了多少个位置?对于六个位置。这意味着订单将为6。在这种情况下,顺序是正的(我们移动了不等于0的数字的整数部分中的点)。标准化形式的最终条目:1.015 * 10⁶。我们可以将这个数字写成这样的形式:1.015E6(其中E6是十进制数的指数,即10的6次方)。我们来测试一下自己。数字的指数表示法只不过是一个数字(尾数)和另一个数字(指数)的乘积。如果将 1.015 乘以 10⁶ 会发生什么? 1.015*10⁶ = 1.015*1000000 = 1015000。这是正确的。这种方法(标准化)有助于创建明确的记录 指数形式的数字,如上所述。 示例 2. 让我们以标准化形式写出十进制实数0.0098。让我们突出显示数字的基数- 它等于10(十进制数字系统)。让我们选择数字的尾数- 它等于9.8(数字的整数部分等于 0,这意味着我们将点向右移动到第一个有效数字(位于从 1 到 9 的范围内) . 我们确定数字的顺序-我们将点移动了三个位置,这意味着顺序是3。正数是负数还是负数?由于我们将点向右移动(在数字的小数部分),因此阶(幂)将为负数。归一化形式的数字的最终记录是9.8 * 10ˉ39.8E-3。我们再检查一下自己。将 9.8 乘以 10ˉ3。9.8 * 10ˉ3 = 9.8 * 0.001 = 0.0098。没错。 示例 3. 让我们以标准化形式写出十进制实数3.56 。选择该数字的基数- 它等于10(十进制数字系统)。选择该数字的尾数- 它等于... 3.56(整数数字的一部分是一位数,不等于 0。这意味着该点不需要移动到任何地方,数字本身就是尾数。)让我们强调一下基数的顺序:尾数应该是多少,等于数字本身,相乘以使其不变?每单位。这意味着订单将为零。归一化形式的数字的最终记录是3.56 * 10°3.56E0。 4. 在计算机内存中存储实数:float 和 double。 4.1 float 和 double 类型。 让我们进入讲座的重点部分。我们已经知道,Java 中有两种类型的实数:floatdoublefloat类型在计算机内存中占用32位,可以取[3.4E-38;范围内的值] 3.4E+38)(即3.4*10ˉ³⁸(含)至3.4 * 10³⁸(不含))。 重要的细微差别 1.浮点数可以是正数也可以是负数。上面的范围用于指示浮点范围中包含的数字的模数。 重要的细微差别 2. 10^3⁸ 分别约等于 2 ^^27,10ˉ^^^^ 约等于2^^^^7。这样,浮点数绝对值的区间就可以写成[3.4 * 2ˉ12⁷; 3.4 * 212⁷)。double 类型占用两倍的计算机内存 -64位并且可以接受[-1.7E+308;范围内的十进制值] 1.7E+308)分别。 4.2 二进制数的指数标准化形式。 我们知道,数字在计算机内存中以二进制形式存储。因此,我们将数字1560.256(浮点型)转换为位置形式的二进制: 11000011000.01000001100。您可能会认为这就是它存储在计算机内存中的方式。但事实并非如此!在计算机内存中, floatdouble 类型(真正的浮点类型)以指数归一化形式存储,但幂的底数是 2而不是 10。这是因为,如上所述,所有数据都在计算机以二进制形式(位)表示。一定数量的计算机内存被分配给一个数字。让我们以标准化指数形式表示正数15.21.52*10^。接下来,让我们使用相同的算法,以指数归一化表示法来 表示其二进制“孪生” 1111.00110011001 : 1) 基数将等于 2 2)尾数将等于 1.11100110011001 3) 度数将为正且等于 3 (该点向左移动 3 位)在十进制中。让我们将其转换为二进制系统:11。因此,在二进制指数归一化形式中,它将是 1.11100110011001 * 2^1。 4.3 在计算机内存中存储浮点数的指数归一化二进制形式。 因此,我们发现实数将以指数归一化二进制形式存储在计算机内存中。它在记忆中会是什么样子?我们以float类型为例。计算机为每个浮点数分配32 位它们的分布如下。该图示意性地显示了计算机中为 32 位浮点数分配的内存。 请勿阅读:))) 计算机内存中的实数。 正在开发中!!! - 5 位编号以红色表示。 绿色表示分配的一块内存(1位),用于存储数字的符号。 黄色表示分配的一块内存,用于存储数字(8 位)的指数形式的移位幂(阶)。 蓝色的表示一块分配的内存,用于存储没有隐式单元的数字的归一化尾数(23 位)。让我们仔细看看。 1) 符号位。最高有效位(左起第一个)始终分配用于存储数字的符号(如果数字为负则为 1,如果数字为正则为 0)。编程中的数字零可能是一个例外,零可以是负数也可以是正数2)接下来是以2为底的指数的次数(阶)位。为此,分配了8位。我们知道,浮点数 的指数次数既可以是负数(对于整数部分为 0 的数字,请参见第 3.3 段),也可以是正数(对于整数部分不为零的数字),范围从 2ˉ12⁷ 到 2127 。理论上,我们应该分配一位来确定指数的符号,就像符号位的情况一样。但事实并非如此。 为了不浪费一点时间来确定指数的符号,浮点数向指数添加半个字节+127 (0111 1111) 的偏移量。因此,计算机存储的不是 2ˉ12⁷ 到 212⁷ 的幂范围,而是 0 到 +254的幂范围 ——所有幂值都是正数,不需要在符号上浪费额外的字节。事实证明,指数的值相对于可能的值移动了一半。这意味着要获得指数的实际值,必须从内存中存储的值中减去该偏移量。如果存储在内存中的指数值小于偏移量(+127),则指数为负:这是合乎逻辑的。 例子。让我们执行负度-18 的移位。我们加上偏移量+127,我们得到度数+108的值(在计算中不要忘记度数0)。我们将度数转换为二进制形式: 1101100 但是为度数分配了 8 位内存,这里我们得到一个 7 位数字。计算机在空的、未被占用的高位(位)处添加 0。 结果是该度数将作为01101100存储在计算机的内存中。让我们看看:+108 < +127,这意味着度数实际上是负数。考虑下面这个有趣的表: 它显示了二进制和十进制系统中浮点数标准化形式的幂的所有可能值。正如我们所看到的,在二进制系统中+127恰好是整个字节(8位)的一半。 3)剩下的23位保留给尾数 请勿阅读:))) 计算机内存中的实数。 正在开发中!!! - 十一点。但对于归一化二进制尾数,最高有效位(也称为归一化尾数的整数部分)始终等于 1(称为隐式一),因为尾数的数字位于1<=M<2范围内(并且还记得讲座的第 2.1.1 段)。唯一的例外是数字 0。将单元写入分配的 23 位并浪费内存是没有意义的,因此尾数的其余部分(其小数部分)被写入分配的 23 位。事实证明,本质上浮点数的有效部分的长度为 24,其中少存储了一位。 一个重要的细微差别。让我们记住,当将十进制小数转换为二进制数时,二进制系统中的小数部分通常会变得很大。而我们只有 32 位来存储浮点数。在这种情况下,二进制分数的最低、最低有效数字(请记住本讲的第 2.1.2 段)将不会包含在分配的内存中,并且计算机将忽略它们数字的准确性将会丢失,但是,你看,这是最小的。换句话说,小数浮点数的精度小数点后6-7位。 4.4 将双精度数的指数归一化二进制形式存储在计算机内存中。double 类型的实数在计算机内存中的存储方式与浮点数相同,但有一些特征除外双精度数在计算机内存中具有 64 位。它们的分布如下(也是从左到右的顺序): 1)符号位(见4.3段)。我们知道该位的数量将为632) 度(阶)。双精度数被分配11 位来存储它。还进行了度数转换,但对于双数,它将等于+1023。 3) 尾数(重要部分)。双精度数分配52 位(数字)来存储它。另外,尾数(隐式单位)的精确整数部分不会存储在内存中。还值得注意的是,小数双精度数的精度约为小数点后 16位。 4.5 在计算机内存中表示十进制实数的示例。 我们讲座的最后一点将是一个将十进制数字系统的分数转换为其在计算机内存中存储的形式的示例,以巩固对该主题的理解。 示例 1. 取一个数字-4.25浮子型。让我们以二进制数字系统中的指数归一化形式呈现它,记住我们在本讲座中介绍的所有内容。 1)将数字的整数部分转换为二进制形式: 4/2 = 2(除0的余数) 2/2 = 1 (除0的余数) 整数部分在二进制中将 等于100 。2)将数字的小数部分转换为二进制形式。0.25*2 = 0.5 ( 0 ) 0.5*2 = 1.0 ( 1 ) 小数部分在二进制中将 等于0.01 。3)因此,-4.25₁0 = -100.0124)让我们将数字 -100.012 转换为二进制数系中的指数归一化形式(这意味着幂的底数为 2)。-100.01² = -1.0001 *2² 让我们将度数值从十进制格式转换二进制格式。2/2= 1(余数0) 次数为10 2 。 我们得到二进制指数归一化形式的数字 -4.25₁₀ 将等于-1.0001 * 21° 让我们写下它在计算机内存中的样子。 符号位将为1(负数)。 指数偏移量等于 2+127 = 129₁₀ = 100000012我们 从尾数中删除隐含的 1 ,我们得到00010000000000000000000(我们用零填充未占用的低位)。 底线。1 10000001 00010000000000000000000 - 这就是数字 -4.25 在计算机内存中的存储方式。 示例 2. 将浮点数 0.75₁0 转换为计算机内存中的二进制存储格式。结果应该是0 01111110 100000000000000000000000。感谢您的关注。
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION