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)?

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

  • 相关阅读:
    003 01 Android 零基础入门 01 Java基础语法 01 Java初识 03 Java程序的执行流程
    002 01 Android 零基础入门 01 Java基础语法 01 Java初识 02 Java简介
    001 01 Android 零基础入门 01 Java基础语法 01 Java初识 01 导学
    001 Android Studio 首次编译执行项目过程中遇到的几个常见问题
    Dora.Interception,为.NET Core度身打造的AOP框架 [2]:以约定的方式定义拦截器
    Dora.Interception,为.NET Core度身打造的AOP框架 [1]:更加简练的编程体验
    监视EntityFramework中的sql流转你需要知道的三种方式Log,SqlServerProfile, EFProfile
    轻量级ORM框架——第二篇:Dapper中的一些复杂操作和inner join应该注意的坑
    轻量级ORM框架——第一篇:Dapper快速学习
    CF888G Xor-MST(异或生成树模板)
  • 原文地址:https://www.cnblogs.com/linkzijun/p/6151418.html
Copyright © 2011-2022 走看看