zoukankan      html  css  js  c++  java
  • 对于c语言int类型和float,以及double类型表示范围的计算

    首先说一下我原来错误的认识

    int是32个bit,

    如果我们把第一位理解为符号位,那么很显然int的范围是-(2^31-1)~2^31-1

    但是实际上我们都知道int的最小值是-2^31次。。

    为什么会这样呢。。首先对于这个问题困惑的话说明你的逻辑不够强

    因为如果第一位是符号位那么上面的分析必然是正确的。。而且按照上面的表示方法,我们显然可以发现

    有两个零,一个是+0,一个是-0

    然而实际上好像并没有这么一说

    所以说。。从这里。。正常的逻辑思维应该得出一个结论。。那就是c语言的int表示方法并不是我们想的那样

    那么我们用x表示一个值。。+,-符号来表示正负号,等号右侧用来表示这个数在计算机里存储的值。。我们都知道计算机是没法存储正负号的(硬件)(额似乎不太恰当)

    那么根据int的表示方法的hash他是怎么工作的呢

    +x=x

    -x=~(x)+1

    除了要注意按位取反表达式。。我们还要注意需要把规定位数的两个数每一位对齐。。高位和过低都截断(?)

    那么这样我们就可以发现。。-(2^31)=~(2^31)+1

    这个太长啦。。我们举一个短一点的例子来算一下

    -(2^3)=~(2^3)+1=2^3

    -1000=0111+1=1000

    哇哦好神奇。。这个就是4位数能表示的最小负数。。4位可以表示的最小负数可以用2^3来表示

    那么同理。。32位整数能表示的最小负数就可以用2^31来表示。。显然可以存下的啊

    所以说经过计算我们就发现了。。int的范围是-(2^31)~(2^31-1)

    ===========================================================================

    研究完了int我们再来研究一下浮点数

    那么我们来研究一下float的表示方法

    此时我们是按照IEEE754标准来定义存在计算机里面浮点数的数据结构

    那么对于float来讲。。它是一个32位浮点数

    我们按照最低位是第0位来讲

    首先这个32bit的位串要分成三部分。。符号位。。阶码。。尾数

    我解释一下啥叫符号位。。第31位是符号位,0:+,1:-

    啥是阶码呢。。。阶码是用来表示这个

    1.xxx*2^x的x的大小的。。

    首先这个标准规定了都用这种方式来表示浮点数

    1.0是最小的。。1+1-2^(-23)是最大的基数。。(前面那个我都管它叫基数)

    我用10进制的小数举个例子。。比如说。。3位小数的最大值是多少呢。。

    显然我们知道是0.999那么其实它等于1-10^(0-3)

    那么同理我们可以知道23位尾数的的小数的二进制最大小数可以表示成1-(2^(0-23))

    然后我们就知道了。。那我这个x要有正有负才可以就是说。。小数点两个方向都可以浮动

    但是他的这个存的策略是。。我只存正数。。等到我要取出来计算并且表示的时候

    我用一个偏移量把它拆成两半。。一半大于零。。一半小于零

    那么实际上对于float的这个尾数的存储策略的话。。是没有用到状态压缩的。。

    它的尾数是多少我们就存多少。。如实复制即可

    =================

    那么对于浮点数这个东西我们还要注意

    你怎么表示零。。

    出现了1/非常小但不为零的小数=》无穷 你怎么处理

    首先对于零的问题。。你尾数域默认最高有效位是1...所以没有存它。。

    但是既然最高有效位不为0.。你怎么表示真正的0呢

    所以这时候他们的策略是牺牲状态空间来特判表示0

    那么对于无穷的情况呢?同理。。特判

    当阶码全为零,尾数也全为零表示的真值是真正的0,并不是用很小的数逼近

    当阶码全为1,尾数全为零表示的是无穷

    根据符号位有,+0,-0,正无穷和负无穷

    对于阶码全为1,尾数不为零的情况。。我们表示的是一个NaN非数,表示运算无效

    ====================

    知道了上面这些我们就可以来计算float类型的值的范围了。。

    由于这里的表示方法正数和负数只差一个符号

    所以我们只考虑它的绝对值的范围就好了

    即1.xxxx*2^x

    那么我们知道阶码不存负数。。

    所以上面那个x并不等于阶码的大小。。而是等于阶码E-127

    为什么呢。。

    我们知道E用8个bit存。。那么最大表示11111111=2^8-1

    也就是255,那么我们知道这个数被用来特判无穷大和NaN

    最小是0,用来特判0

    所以对于除此之外的数。。

    我们可以用1~254。。

    但是你要有正有负啊。。分成两半。。

    都减去127就变成了-126~127

    这样就变成了x的范围

    知道了1.xxx的范围和2^x的范围。。计算就很轻松了。。

    绝对值

    最大是(1+1-(2^(-23)))*2^127

    最小是1.0*2^(-126)?

    那么再具体的话。。加上正负号就行了。。

  • 相关阅读:
    类的加载次序与继承
    十进制转二进制算法
    面象对象与面象过程内存分区
    C/C++单向链表
    字符串与数字互相转换算法
    C#模拟进度条
    数据类型与类型转
    win7删除一些顽固的文件夹
    快速卸载VS2015的办法
    Js获取图片原始宽高
  • 原文地址:https://www.cnblogs.com/linkzijun/p/6151418.html
Copyright © 2011-2022 走看看