精华内容
下载资源
问答
  • 2021-07-29 01:21:46

    小数在内存中是如何存储的?

    文本关键字:小数、float、double、浮点数、精度

    一、IEEE 754(二进制浮点数算术标准)

    在学习进制转换时,我们了解到:我们经常使用的十进制数是转换为二进制进行存储的,只需要按照顺序将转换后的结果放在对应的位置上就行了。其实小数的存储也是基于二进制的,不过由于小数由整数部分和小数部分组成,为了方便表示和比较,会使用另外的方式来存储。

    IEEE 754是最广泛使用的浮点数运算标准,在标准中规定了四种表示浮点数值的方式:

    单精度:32位 - 4字节

    双精度:64位 - 8字节

    延伸单精度:43+

    延伸双精度:79+

    对于进制转换不清楚的同学可以进传送门:进制之间如何转换?

    1. 存储结构

    小数在内存中的存储由三部分组成,分别是符号、阶码(或称指数)、尾数。符号位我们很熟悉,只占一位,并且出现在最高位,0为正,1为负。

    单精度:符号1位,阶码8位,尾数23位

    双精度:符号1位,阶码11位,尾数52位

    延伸精度很少使用,不做介绍

    3fdce83e2f8b8d1af742e34bf06f1226.png

    2. 存储方式

    一个十进制的小数在进行存储时,首先要将整数部分与小数部分都转换为二进制,然后再整理成类似科学计数法的形式,即:移动小数点,使得小数点的左边只有一位,并且只可能为1(因为是二进制),小数点右侧的部分即为尾数部分,移动小数点的位数将会被记录在指数部分中。为了能够透彻的理解十进制小数转化存储在内容中的过程,我们还需要了解一个概念:阶码。

    二、阶码(指数)

    1. 定义

    对于一个二进制数,我们总可以把它整理成:尾数 ✖️ 2的P次方的形式,其中P就被定义为阶码,我们也可以认为2是底数,P为指数,以整数形式表示。

    2. 为什么小数被称作浮点数?

    定点小数

    在早期计算机中,为了节省硬件资源,阶码P的值是被固定的,那么小数的表示形式也同时被固定了。规定第一位为符号位,小数点固定在第一位后面,这种小数是纯小数,被称为定点小数。

    浮点小数

    与定点小数相对的,如果阶码P可变,那这种小数表示法就被称为浮点表示,这样的数也就被称为浮点数了。更为重要的一点,P指明了小数点的位置。

    3. 移码

    明白了阶码的概念,也了解了浮点数的前世今生,那么我们大费周章的说这个概念干什么呢?没错,重点来了,就是为了这个移码的码制。在进行小数点移动时,需要先将十进制数转换为二进制,再去移动小数点,保证小数点左侧只有一位,且数值为1。

    对于绝对值大于2的数,这个时候我们向左移动小数点,对应的指数为正数;

    对于一个绝对值小于1的数,这个时候我们向右移动小数点,对应的指数为负数;

    绝对值在1和2之间的数嘞?这个时候不用移动好叭。。。

    那么问题就来了,我们的指数有的时候正,有的时候负。But!更为严重的问题是,在指数部分对应的区间并没有符号位这个东西,最前面的符号位代表的是小数本身的正负,这就使得存储和比较都变得困难,所以我们希望通过一种修正的方式避开正负号的问题。怎么做呢?以float为例,指数部分长度为8。

    原有带符号位的8个bit的存储范围是-128 ~ 127(不明白的同学可以进传送门为什么一个byte的存储范围是-128~127?),也就是说可以记录-128次方到+127方之间的所有指数值。如果忽略符号位,把它也当做一个数据的存储位,那么范围就是0~255,我们取这个数的一半作为修正值,即:127,把每次移动小数点后获得的指数值都加上127。

    小数点向左移动3位,对应的指数为+3,存入指数部分的值即为130的二进制表示

    小数点向右移动2位,对应的指数为-2,存入指数部分的值即为125的二进制表示

    这样的好处就是避开了符号的问题,同时,原有的指数的值也得到的了保存,取出的时候减掉127就好了。那么直观的讲,原来的范围是-128 ~ 127,加上127之后范围应该变成-1 ~ 254,貌似对应关系有问题呀~这其实是一个很简单的二进制换算问题,对于有符号数,最高位为符号位,用1代表负数,-128的补码为:1000 0000,但是这在无符号数眼里的值为128,-1的补码为:1111 1111,但是在无符号数眼里值为255。所以我们不能直接通过加减法得出这个取值范围,而应该结合二进制存储的规则(不明白的同学可以二进传送门查看补码相关的知识:为什么一个byte的存储范围是-128~127?)。

    三、小数的进制转换

    说了这么久,我们用几个例子来给大家演示一下,会给大家列出小数在内存中存储的完整表示,在这之前还是需要先学习一下十进制小数应该怎么转换为二进制(读者内心:我太难了。。。)。

    1. 十进制转二进制

    小数分为整数部分和小数部分,整数部分的转换照常进行,不断的除2得到,小数部分刚好是不断的乘2得到,一直到小数部分为0,或者已经达到了对应的精度,以69.3125为例。

    整数部分:69 = 64 + 4 + 1 = 2^6 + 2^2 + 2^0

    对应的二进制数为:0100 0101

    小数部分:转换过程如下 -> 不断乘2,取出结果中的整数部分

    对应的二进制数为:0101

    f52415fb91119fdd0925b4727039f298.jpg

    最终转换结果:0100 0101.0101

    2. 二进制转十进制

    由二进制转换为十进制比较简单,就是运算规则做相反的运算,整数部分是做除法得到的,那么转换回去的时候就是做乘法,小数部分是做乘法得到的,那么转换回去的时候就做除法,以0100 0101.0101为例。

    整数部分:2^6 + 2^2 + 2^0 = 64 + 4 + 1 = 69

    小数部分:0 x 2^-1 + 1 x 2^-2 + 0 x 2^-3 + 1 x 2^-4 = 0.3125

    可以看到规律其实是统一的,就是从左至右根据二进制数乘以2的n次方,从左至右n的值不断递减,在个位处,n的值为0,进入小数部分n的值为负数,在运算上的体现为除法。

    3. 小数在内存中的存储表示

    99.9

    99.9的二进制表示:1100011.111001100110011001100110011001100110011001101。现在我们需要将小数点左移6位,对应的指数值为+6。此时小数点右侧的位数为51位,这些将会被存放在尾数部分,如果使用double类型可以将数据全部记录,但是如果使用float类型,由于尾数部分只有23位,所有只能记录部分的数据,误差也就产生了!

    整理一下,符号位为0,指数部分为6+127=133,尾数部分直接丢进去,能装多少装多少,以float为例。

    最终表示为:0 10000101 10001111100110011001100

    0.226

    0.226的二进制表示:0.0011100111011011001000101101000011100101011000000100001。此时小数点需要右移3位,对应的指数值为-3,剩下的尾数部分同样能塞多少塞多少。

    整理一下,符号位为0,指数部分为-3+127=124,以float为例。

    最终表示为:0 1111100 11001110110110010001011

    四、float与double

    1. 精度范围

    从上面的例子我们可以看到,当一个小数在存储的过程中,误差就已经产生了,而且由于是转换为二进制存储,我们很难对所有的小数进行判断是否在存储时丢失了精度。看下面几个例子:

    public static void main(String[] args) {

    Float f1 = 99.99999f;

    System.out.println(f1);// 输出结果:99.99999

    // 貌似很正常啊,其实float的内心慌的一批

    Float f2 = 99.999999f;

    System.out.println(f2);// 输出结果:100.0

    // 此时终于暴露了吧?在存储时就已经丢失了精度,在参与小数计算时更加暴露无遗

    }

    float精度:小数点后6~7位

    double精度:小数点后15~16位

    丢失精度的原因经过上面的分析和例子相信大家应该很清楚了,我们按照常规流程进行二进制转换后得到的尾数部分可能很长,但是以单精度或双精度进行存储时只能存储一部分,那么必然导致精度的丢失。

    2. 解决精度不足

    float和double作为基本数据类型使用起来当然是比较方便,但是精度的问题会造成不准确,虽然我们可以通过使用保留几位小数的方式勉强应对,但是为了保证高精度通常会使用BigDecimal,具体用法不在此赘述,将在后续文章中说明。

    3. 与长整型的比较

    我们在接触基本数据类型的时候曾经碰到过一个大哥大,曾以为能够装进去很大很大的整数,毕竟是8字节的身材,但是仔细那么一比较,存储范围竟然还比不过4字节的float,更不要说同等身材的double了。

    long的存储范围:-2^63 ~ 2^63 - 1

    float:-2^128 ~ 2^128

    double:-2^1024 ~ 2^1024

    以上数据只是表示一个量级,不能代表浮点数的精确范围,不过这也足够碾压long类型了,以至于long类型可以隐式转换为float,这就解决了我们的一个疑问,为什么4字节的float存储范围比8字节的long类型还要大?自然是存储方式不同。

    更多相关内容
  • 计算机小数存储

    千次阅读 2019-09-30 09:48:59
    我们在最初学习C语言的时候,学习数据类型的时候接触到了浮点数,知道了它被用来存储小数,但是为什么在计算机小数要称为浮点数呢? 在C语言中文网上,我知道了数据的存储分为定点数和浮点数,它们的命名方式也取...

    我们在最初学习C语言的时候,学习数据类型的时候接触到了浮点数,知道了它被用来存储小数,但是为什么在计算机中小数要称为浮点数呢?

    在C语言中文网上,我知道了数据的存储分为定点数和浮点数,它们的命名方式也取决于它们存储数据的方式

    C语言小数存储的方法有两种:定点数和浮点数

    定点数

            顾名思义,定点数就是小数点位置固定的数

            下图以32bit机器为例,表示124.25

            第一位数据为符号位,其余为数据位;数据位又被划分为整数部分和小数部分

            使用定点数表示小数,小数点的位置固定

            定点数的优缺点:

            定点数的优点就是可以精确表示想要表示的数值,不会像浮点数一样计算机内部无法精确的表示一些数值

            定点数的缺点就是不适用于表示特别大或者特别小的数值

    浮点数

            和定点数不同的是,浮点数表示小数时,小数点的位置是浮动的、不固定的

     

            浮点数的存储格式,一般按照IEEE 754标准,表示方法如下:

            最高的 1 位是符号位 s,接着的 8 位是指数E,剩下的 23 位为有效数字 M

            浮点数的表示类似于科学计数法

    十进制二进制浮点表示
    51011.01 x 2^2
    910011.001 x 2^3
    100011001001.100100 x 2^6
    0.1250.0011 x 2^-3

                    数值范围不受限制,表示格式也不受限制,因此它能够表示比整数更大的数据;但是它的运算速度比整数运算低,且容易丢失精度

     

    展开全文
  • 小数计算机中的存储1. 定点数2. 浮点数2.1 科学计数法2.2 浮点数的存储2.3 浮点数的精度损失 0. 小数计算机中的存储 两种方法: 定点 浮点 1. 定点数 顾名思义,小数点的位置固定的。 也就是说,用固定数量的...

    0. 小数在计算机中的存储

    两种方法:

    • 定点
    • 浮点

    1. 定点数

    顾名思义,小数点的位置固定的。

    也就是说,用固定数量bit存储整数部分,也用固定数量bit存储小数部分,另外再用一个bit存储符号位。

    计算时,将三个部分拼接起来,加个小数点即可。

    优点:小数点位置固定,方便计算。
    缺点:表示输的范围受限。

    2. 浮点数

    浮点数在计算机中的存储依赖科学计数法。

    2.1 科学计数法

    十进制中,3145使用科学计数法可以表示成 3.145 * 103
    科学计数法一般的表达形式:M * baseE,其中 M 暂且称他为尾数,必须要 >= 1 且 < basebase是进制,10进制就是10,2进制就是2;E是指数。

    任意一个二进制浮点数可以表示成: V = (-1)s x M x 2E

    2.2 浮点数的存储

    综上,若想在计算机中存储一个浮点数,需要保存如下三个数值:

    • 符号位 s,0 或者 1 。
    • 尾数 M ,因为基数M前边说过,必须 >= 1,所以,这个数字1就可以不存了,直接存储后边的小数部分。
    • 指数E

    IEEE 754中规定,32bit的浮点数中(64bit同理),最高 1 bit是符号位,紧接着的 8 bit 存储指数 E,最后的 23 个bit存储尾数 M。

    此外,还有一些特殊规定:

    在这里插入图片描述

    2.3 浮点数存储及范围的例子

    在这里插入图片描述
    在这里插入图片描述

    展开全文
  • 三、计算机处理小数时出现错误的原因 3.1用二进制表示小数 二进制:11.101 小数点后表示2的 - XX次方 十进制:10.52 小数点后表示10 的 -XX次方 3.2二进制永远无法表示十进制的0.1 如同十进制无法表示1/3一样,二...

    三、计算机处理小数时出现错误的原因

    3.1用二进制表示小数

    二进制:11.101 小数点后表示2的 - XX次方

    十进制:10.52 小数点后表示10 的 -XX次方

    3.2二进制永远无法表示十进制的0.1

    如同十进制无法表示1/3一样,二进制表格如下:

    二进制数十进制数
    0.00000
    0.00010.0625
    0.00100.125

    2的负多少次方,无论怎么累加都无法得到0.1

    3.3什么是浮点数

    定点数:321.123 小数点是固定的;

    浮点数:0.123x10-8 小数点不是固定的,按照后面的来确定小数点的位置

    浮点数的组成:对于计算机来说,基数是确定的,为2,所以只用三个参数来表示浮点数:符号,尾数,指数

    请添加图片描述

    双精度与单精度浮点数的构成:

    双精度:

    请添加图片描述

    单精度:

    请添加图片描述

    3.4正则表达式和excess系统

    这里的正则表达式:指的是只能用一种特定形式去表示小数,如十进制的科学计数法所规定的一样,二进制也有特定的规则

    浮点数的正则表达式:将小数点前面的值固定为1的规则,让后将1去掉,完成正则,得到尾数部分

    请添加图片描述

    指数部分该如何确定:EXCES

    如单精度的指数部分有8位,最大能表示的为1111 1111 (十进制的255),取它的1/2 ,即0111 1111 =127(小数部分舍弃)表示0;

    举个例子:1~10有十个数字,如果取中间的5作为0, 那么10就表示:10-5 = +5 ,1就代表:1 - 5 = -4 ;这就是所谓的EXCESS系统

    请添加图片描述

    在实际程序中看负数到底是怎么表示的:

    #include<stdio.h>
    #include<string.h> 
    
    int main() {
    	float data;
    	unsigned long buff;
    	int i;
    	char s[34];
    	
    	// 将0.75以单精度的形式保存起来
    	data = (float)0.75;
    	
    	// 将数据复制到4个字节长度的整数变量buff中,然后逐一提取每一位
        // memcpy(viod* des, void* src, unsigned int count)
        // 将src 指针所指的内容复制到dec所指向的位置, 大小为count个字节
    	memcpy(&buff, &data, 4);
        // buff不管0.75的二进制格式(符号位-指数位-尾数位),直接同一对待
        // 看这个0.75二进制码以十进制读出来
    	printf("%lu\n",buff);
    	
    	// 逐一提取每一位
    	for (i =33; i >=0; i-- ){
    		if(i==1 || i == 10)
    			// 在符号位,指数位与尾数位之间加入-分界符来使得表示更加清晰 
    			s[i]= '-';
    		else{
    			// 将buff里的数转换为2进制
    			if(buff % 2 == 1){
    				s[i]='1';
    			} else{
    				s[i] = '0';
    			}
    			buff /=2; 
    			
    		} 
    	} 
    	s[34]='\0';
    	
    	printf("%s\n",s);
    }
    

    结果如下:

    请添加图片描述

    符号位:0 因为0.75是个正数

    尾数部分1000…还原为小数点前为1的形式:1.10000…. = 1* 2的0次幂 + 1*2的-1次幂 = 1.5

    指数部分 0111 1110 = 126 即126 - 127 = -1;

    最终结果 = 尾数部分 x 指数部分 :1.5* 0.5(2的-1次方) = 0.75

    3.5 如何避免出错

    第一种策略:回避策略:允许一定程度的误差

    第二种策略:涉及到金融时,先将小数转换为整数,因为整数计算一定不存在错误,将结果再转换成小数显示出来

    展开全文
  • 本篇的目的就是为了让更多的人...小数在被存储到内存前,首先转换为下面的形式: a * 2n a 为尾数,是二进制形式,且 1 ≤ a ;n 为指数,是十进制形式。 其中,2 是固定的,不需要在内存中体现出来;正负号、指数(n
  • 计算机小数运算

    千次阅读 2020-02-05 16:57:45
    文章目录二进制的小数无法转换的小数浮点数如何保证计算的精度回避策略把小数转换成整数来计算十六进制的使用 二进制的小数 规则:小数点后面部分的位权,第 1 位是 2 的-1 次幂、第 2 位是 2 的-2 次幂 这一规律...
  • 一、概述正整数直接按照源码存储,负整数按照补码存储,那么小数如何存储表示?二、浮点数的概念(IEEE754)浮点数是计算机中用于表示实数的一种方法,类似于科学计数法,如:314.4=3.144x1020.00314=3.14x10-3255=2.55...
  • 首先,依葫芦画瓢:(计算机中的小数分为单精度float和双精度double) 指数的范围如下 最重要的就是尾数部分: 综上,二进制小数的表示方法就完成了 举个栗子: 1101.1011 = 1.1011011 * 23 ...
  • 小数计算机中如何存储

    千次阅读 2021-01-04 14:46:13
    IEEE标准754将浮点数的存储分三个部分:符号位;指数位;有效数字(系数位);单精度浮点数32位=1位符号位+8位指数位+23位有效数字;双精度浮点数64位=1位符号位+11位指数位+52位有效数字
  • 浮点数(小数)在计算机中如何用二进制存储

    千次阅读 多人点赞 2020-08-28 22:39:12
    但是,计算机处理的不仅仅是整数,还有小数,同样小数计算机也是用二进制进行存储的,但是,二进制如何去存储小数呢?计算机对于小数的计算又是否真的丝毫不差呢?本文将进行介绍。 一、用二进制表示小数 二进制...
  • 计算机中的小数运算

    2021-07-14 20:22:02
    但这并不是计算机出现了故障,而是由计算机用二进制表示小数的机制所造成的。下图所示为将二进制数1011.0011转换为10进制数的过程。 整数部分二进制的转换我们已经了解了,从上面我们可以看到,小数部分的二进制...
  • 前言有两个问题一直让我疑惑,第一个计算机存储整数为什么用反码来表示?第二个js中0.1+0.2为什么等于0.30000000000000004,计算机小数是如何存储的? 计算机的原码反码以及补码对于整数来说第一个代表符号位(0为正1...
  • 计算机中的小数

    千次阅读 2019-01-02 19:00:32
    1.JAVA之父James Gosling说过:其实95%的编程者对小数一无所知。     2.没错,在学编程的很长一一段时间里,我们根本没有关心数据在计算机内部到底是怎么表示的,最多知道个什么是寄存器,知道什么是内存,什么...
  • 1. 将0.1累加100次也得不到10 举一个计算机运算错误(无法得到正确结果...计算机之所以会出现运算错误,是因为“有一些十进制数的小数无法转换成二进制数”。 代码清单3-1中程序无法得到正确结果的原因是,因为无法正确
  • 浮点数(小数)在计算机中实际是以二进制存储的,并不精确。 比如0.1是十进制,转换为二进制后就是一个无限循环的数: 0.00011001100110011001100110011001100110011001100110011001100 python是以双精度(64bit)来...
  • 2007-10-31请对计算机中的定点树,浮点数进行如果小数点的位置事先已有约定,不再改变,此类数称为“定点数”。相比之下,如果小数点的位置可变,则称为“浮点数”。⑴ 定点数。常用的定点数有两种表示形式:如果...
  • 文章目录科学计数法二进制推广计算机中的小数EXCESS表示系统特殊情况举例(float)普通情况最大正实数普通情况最小负实数普通情况最小正实数特殊情况最大正实数 科学计数法 科学计数法想必大家都很熟悉了,往往通过...
  • C语言---计算机小数存储

    千次阅读 2017-06-21 17:03:40
    今天在一个老师讲的C语言视频中学到了小数在计算机中的存储方式,特此来分享一下,同时感谢老师的讲解。  在计算机中整数的存储是大多数人能够轻易理解得,比如...然而计算机存储数据的方式都是一样的,并没有区分有符
  • 1.计算机小数数据是如何表示的呢? 原码,反码和补码可以实现正负整数的表示,但是对于小数部分却没办法表示。为了合理的表示小数,定点数确定了小数点的位置,固定了小数的位数,但是这样会导致范围分配不合理...
  • 小数计算机中的储存形式 符号位 阶码 尾数 长度 float 1 8 23 32 double 1 11 52 64 1)32位浮点数的换算: float var = 5.2f; 0.2*2 = 0.4 * 20 = 0.8 * 2 0= 1.6(0.6) * 2 1= 1.2(0.2)*2 1= 0.4 *...
  • 小数存储 计算机小数以二进制(浮点数)形式存储。 首先是一个十进制小数形式,转化成二进制的计算案例。 ———————————————————————————————— 0.8125 转换成二进制 其实这种情况...
  • C语言学习(十一)小数在内存中是如何存储的?定点数与浮点数各自的优势在哪?规格化浮点数与非规格化浮点数又表示什么? 浮点数与定点数 小数在内存中以浮点数形式存储。浮点数并不是一种数值分类,他和整数、小数...
  • 小数计算机的表示

    2019-10-03 06:02:09
    整数在计算机中是可以精确表示的,任何一个整数都可以用二进制来准确表示,但是小数却不行,举个例子:0.75=0.5+0.25(也就是2的-1次方与2的-2次方的和)。但0.76=0.5+0.25+........................,这是无法准确...
  • 浮点数式存储小数在内存中是如何存储的?定点数浮点数   小数在内存中是以浮点数的形式存储的。 浮点数是数字(或者说数值)在内存中的一种存储格式,它和定点数是相对的。 浮点数和定点数中的“点”指的...
  •   大家应该都知道小数转二进制的方法吧,乘2取整,得到积,将积的整数部分取出,再用余下的小数部分乘2,又得到一个积,再将积的整数部分取出,如此进行,知道积中的小数为0,或者达到所要求的精度为止。...
  • 计算机之所以会出现运算错误,是因为“有一些十进制数的小数无法转换成二进制数”。例如,十进制数0.1,就无法用二进制数正确表示,小数点后面即使有几百位也无法表示。因为无法正确表示的数值,最后都变成了近似值...
  • 计算机编程语言里面,小数也称为浮点数,表示小数点的位置是可以“浮动”的。因为,小数一般用科学计数法描述,例如0.1234可以表示为1234e-4,即1234*10^-4。这样的浮点数在计算机中用三部分存储,如下图:符号:...
  • 小数转分数

    2015-10-28 13:15:40
    计算机中,用float或double来存储小数有时不能得到精确值,若要精确表达一个浮点数的计算结果, 最好用分数来表示小数,有限小数或无限循环小数都可以转化为分数,无限循环小数的循环节用括号标记出来。如: 0.9 =...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 58,471
精华内容 23,388
关键字:

计算机如何存储小数

友情链接: chronuxintroduction.zip