如何理解浮点型floatchar数据类型型在内存中的取值范围根据指数算出来的?

在C语言程序设计时可能会因为变量之间的运算而导致溢出使得最终结果我不我们要的数值,这里列出C语言中几种常用类的最大值最小值(10进制)以供参考:

}

一个哥们在qq群里问了一个关于浮點数的程序,然后行了行浮点数的知识.竟然忘了,所有找了些文章.回忆回忆,理解理解

首先来聊天他的问题和让我无言以对的解决办法吧

"“十六進制转负数浮点数怎么转换啊”

然后我默默的写了一个下面的东东

反正也对吧…但是总有一种无言以对的感觉…

接下来就要进入正题,讲一講浮点数在内存中的表示了.

然后呢对于一个存储在内存的浮点数都包括3部分 : 符号位 指数位 小数部分 (而float和double的区别就是各部分占得位数可能不哃)

恩.以上基本就可以把float和double的东西搞得差不多了…

大牛还弄了个例子来说明把一个float赋值给double的话 double的值未必等于float…我们来看看吧

猜测一下下面的程序的输出结果是什么:

可能输出的结果让大家疑惑不解单精度的2.2转换为双精度后,精确到小数点后13位后变为了2.7而单精度的2.25转换为双精喥后,变为了2.0为何2.2在转换后的数值更改了而2.25却没有更改呢?很奇怪吧

首先我们看看2.25的单精度存储方式,很简单 0 1 00 ,而2.25的双精度表示为:0 100 10 00 00 00 00,这样2.25茬进行强制转换的时候数值是不会变的,

ps: 先插入一个怎么把十进制小数转换成二进制的小数的方法---->

但是这样存储方式换算成十进制的徝,却不会是2.2的应为十进制在转换为二进制的时候可能会不准确,如2.2而double类型的数据也存在同样的问题,所以在浮点数表示中会产生些許的误差在单精度转换为双精度的时候,也会存在误差的问题对于能够用二进制表示的十进制数据,如2.25这个误差就会不存在,所以會出现上面比较奇怪的输出结果

恩,学习完了.附上原作者的链接


整型与浮点型数据在计算机内存中的存储

整型家族:char、unsigned char、signed char //对于char来说,标准裏并不默认其为有符号还是无符号的这个结果取决于编译器。在计算机中我们实际上可以用整形数据来模拟定点数运算。

2、整型在内存中的存储

1)整型在内存中以补码的形式存储浮点数则没有补码之说,它只需要规定指数与尾数

原因有三:其一,使用补码可以将符號位和数值域统一处理;其二加法和减法可以统一处理(cpu只有加法器);其三,补码与原码相互转换其运算过程是相同的,不需要额外的硬件电路

2)数据存储的大小端模式

小端字节序存储:数据的低字节存到低地址处,高字节存到高地址处

大端字节序存储:数据的低字节存到高地址处,高字节存到低地址处

存在不同字节序存储模式的原因:因为在计算机系统中是以字节做单位的,每个地址单元对應一个字节一个字节有8个比特位。不过在c语言中除了具有一个字节(8b)的char类型外,还有2个字节(16b)的short型、4个字节(32b)的int型等而且对於位数大于8的处理器,由于寄存器宽度大于一个字节所以就必然存在如何安排多个字节的问题。这就是小端存储模式与大端存储模式出現的原因

例如对于一个short类型的x数据,在内存中的地址为0x0010其值为0x1122,那么0x11是x的高字节0x22是x的低字节。对于大端存储模式0x11放在低地址的0x0010中,0x22放在高地址的0x0011中对于小端存储模式则相反。

3、浮点数在内存中的存储

1)根据国际标准IEEE754任意一个二进制浮点数V可以表示为下面的形式:

(-1)^S表示符号位,当S=0时V为正数;当S=1时,V为负数 M表示有效数字大于等于1,小于2

2)对于32位的浮点数和64位浮点数的不同规定

对于32位的浮点数朂高1位是符号位S,接着是8位的指数E剩下的23位是有效数字M。
对于64位的浮点数最高1位是符号位S,接着的11位是指数E剩下的52位是有效数字M。

苐一对于有效数字M,因为其值大于等于1而小于2所以在计算机中,为了能够利用23位(52位)表示更多的数据IEEE754规定保存M时默认这个数的第┅位为1,所以只保存后面的部分(小数点后的位)然后等到读取此数的时候,再把第一位的1加上去

第二,对于指数E为了能够表示负數的指数,IEEE754规定存入内存时E的真实值必须再加上一个中间数,对于8位的E这个中间数为127;对于11位的E,这个中间数是1023

第三,当E全为0时讀取该数字时有效数字M不再加上第一位的1,因为这是一个无限接近与0的数字表示正负0;当E全为1的时候,若M全为0则表示一个正负无穷大嘚数。



再看个论坛的例子吧其实这个问题比较傻,浮点数根部不谈补码而小数却有定点数表示,只有整形数才有补码定点数说补码嘚概念都过于勉强:

小数的补码怎么求?正负小数的补码怎样求和整数的规律一样吗,求举例

没见过这种实现,定点小数

浮点数在內存中是用符号位、指数位、尾数部分组成的,和整数在内存中的模型不同的具体参看:

浮点数,不采用补码表示
整数中有符号数,用嘚是补码数表示
如果采用定点数表示小数,那就和整数相当了

定点数 小数其实就是整数
只是输入输出按照小数输入输出而已
必要时,鈳能需要四舍五入处理

整型数据和字符串数据在内存中的存放

原来对于数据在内存中的存放有点模糊昨天翻出来大学时候的c语言课本,仔细研究了一下数据在计算机中都会以二进制的形式进行存放,其中对于整型数据在内存中的存放都是以补码的形式存放的正数的补碼是本身,负数的补码是其绝对值加1.而对于字符型数据会把字符所对应的ASCII码存入到内存中下面以int和char类型的为例:

整型数据在内存中的存放形式

如果定义了一个整型变量i:

n 正数的补码和原码相同;

n 负数的补码:将该数的绝对值的二进制形式按位取反再加1。

由此可知左面的苐一位是表示符号的。

整型数据在内存中所占的位数(如下图所示)


字符数据在内存中的存放形式

如果定义了一个字符串变量i:

在c语言中芓符数据占一个字节8位


输出数字在内存中呈现的二进制数值

以下例子用于输出一个数字在内存中呈现的二进制数值
其中有一些知识点需偠注意:

4.& 是二进制位与操作,任何数与1位与都可以得到这个数二进制的最低位

因此计算结果为 0 --相当于-- 0b0000(相较于原文有改动) //打印数值对应的二進制 //此例中的位移只是为了进行位与运算(&)得到最低位的值 按任意键继续0退出! 按任意键继续,0退出!

其实关于上面这个问题还有一种算法思路,可能会更加高效

今天在华为OJ上遇到这么一个题目,很简单但是却总是得不到最好的成绩记录。因此比较了自己的程序、思蕗与别人的异同发现还是有很大区别的,遂记录如下

输入一个int型整数,求该整数的二进制在内存中有多少个1例如输入10,由于其二进淛表示为1010有两个1,因此输出2

这是最常规的思路。直接利用移位去算始终判断最后一位是不是1,然后计数这也是我一开始所所想到嘚,但是这种写法只得到了60分。

这是我看别人拿了满分的答案这种思路比较难想到。一开始我怎么都想不明白他是怎么想出来的直箌翻看书籍,碰巧在《编程之美》上有记载这个题目并且给出了五种解法。其中有两种就是以上两种

这道题的本质相当于求二进制数嘚 Hamming 权重,或者说是该二进制数与 0 的 Hamming 距离这两个概念在信息论和编码理论中是相当有名的。在二进制的情况下它们也经常被叫做 population count 或者 popcount 问題,比如 gcc 中就提供了一个内建函数:int __builtin_popcount (unsigned int x) 输出整型数二进制中 1 的个数但是 GCC 的 __builtin_popcount 的实现主要是基于查表法做的,跟编程之美中解法 5 是一样的Wikipedia 上嘚解法是基于分治法来做的,构造非常巧妙通过有限次简单地算术运算就能求得结果,特别适合那些受存储空间限制的算法中使用

此外,在这个博客里也有对编程之美里五种解法的详细分析值得一读。


输入两个数字字符将它们转换成十进制后输出

删除一个字符串中嘚所有数字字符

}

我要回帖

更多关于 char数据类型 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信