计算机的小数运算

二进制的小数

规则:小数点后面部分的位权,第 1 位是 2 的-1 次幂、第 2 位是 2 的-2 次幂
这一规律并不仅限于二进制数,在十进制数和十六进制数中也同样适用
例子
将 1011.0011 转换为十进制的数?
图:
在这里插入图片描述

负指数幂的推导
图:
在这里插入图片描述

0 指数幂推导
零指数幂推导:
图:
在这里插入图片描述

无法转换的小数

//result = 10.000002
    public static void show1(){
        float sum = 0;
        int i;
        for(i = 0; i < 100; i++){
            sum += 0.1;
        }
        System.out.println(sum);
    }

二进制数转换为十进制小数对应表
图:
在这里插入图片描述
原因汇总
(1)计算机这个功能有限的机器设备,是无法处理无限循环的小数的
(2)不管增加多少位, 2 的-○○次幂怎么相加都无法得到 0.1 这个结果(确实存在无法转换)
(3)无法用十进制数来表示 1/3 是一样的道理。1/3 就是 0.3333…

浮点数

分类
双精度浮点数类型用 64 位
单精度浮点数类型用 32 位来表示全体小数

浮点数具体组成
浮点数是指用符号、尾数、基数和指数这四部分来表示的小数
图:
在这里插入图片描述

引用:双 精 度 浮 点 数 能 够 表 示 的 正 数 范 围 是 4.94065645841247×10-324~1.79769313486232×10 308 ,负 数 范 围 是-1.79769313486232×10 308 ~ -4.94065645841247×10-324 。 单 精 度 浮 点 数 能 够 表 示 的 正 数 范 围 是1.401298×10 -45 ~3.402823×10 38 ,负数范围是-3.402823×10 38 ~-1.401298×10-45 。
不过,正如正文中所介绍的那样,在这些范围中,有些数值是无法正确表示的

符号部分: 是指使用一个数据位来表示数值的符号。该数据位是 1时表示负,为 0 时则表示“正或者 0”。

尾数部分: 用的是“将小数点前面的值固定为 1 的正则表达式”
图:
在这里插入图片描述

正则表达式:按照特定的规则来表示数据的形式即为正则表达式。除小数之外,字符串以及数据库等

指数部分: 用的则是“EXCESS 系统表现”
好处:使用 8 位二进制数 00000000 - 11111111(十进制数 255)就能够表示对应的正、负情况了
对应图:
在这里插入图片描述

如何保证计算的精度

回避策略

无视这些错误。根据程序目的的不同,有时一些微小的偏差并不会造成什么问题
例如:
假设使用计算机设计工业制品。将 100 个长 0.1 毫米的零件连接起来后,其长度并非一定要是10 毫米,10.000002 毫米也没有任何问题。一般来讲,在科学技术计算领域,计算机的计算结果只要能得到近似值就足够了。那些微小的误差完全可以忽略掉

把小数转换成整数来计算

分析:计算机在进行小数计算时可能会出错,但进行整数计算(只要不超过可处理的数值范围)时一定不会出现问题

实例:
Decimal的原理就是把小数放大10的N次方倍,将小数点移动到后面,这样利用都是整数,就保证了精度。

BigDecimal 由任意精度的整数非标度值 和32 位的整数标度 (scale) 组成。如果为零或正数,则标度是小数点后的位数。如果为负数,则将该数的非标度值乘以 10 的负scale 次幂。因此,BigDecimal表示的数值是(unscaledValue × 10-scale)。

BCD编码方式

定义:8421 BCD码是最基本和最常用的BCD码,它和四位自然二进制码相似,各位的权值为8、4、2、1,故称为有权BCD码。和四位自然二进制码不同的是,它只选用了四位二进制码中前10组代码,即用0000~1001分别代表它所对应的十进制数,余下的六组代码不用

好处:相对于一般的浮点式记数法,采用BCD码,既可保存数值的精确度,又可免去使计算机作浮点运算时所耗费的时间。

例如:”93.14“
9用4位二进制数码表示为:1001
3用4位二进制数码表示为:0011
1用4位二进制数码表示为:0001
4用4位二进制数码表示为:0100
组合得到93.14得BCD码:10010011.00010100

思路:因为可以精确的使用二进制数字表示了十进制的数了,那么相应的四则运算自然亦不成问题

十六进制的使用

方式:只需在数值的开头加上 0x(0 和 x)就可以表示十六进制数
好处:通过使用十六进制数,二进制数的位数能够缩短至原来的 1/4。位数变少之后,看起来也就更清晰了

摘取BigDecima 源码展示:

    private static final long[][] LONGLONG_TEN_POWERS_TABLE = {
        {   0L, 0x8AC7230489E80000L },  //10^19
        {       0x5L, 0x6bc75e2d63100000L },  //10^20
        {       0x36L, 0x35c9adc5dea00000L },  //10^21
        {       0x21eL, 0x19e0c9bab2400000L  },  //10^22
        {       0x152dL, 0x02c7e14af6800000L  },  //10^23
        {       0xd3c2L, 0x1bcecceda1000000L  },  //10^24
        {       0x84595L, 0x161401484a000000L  },  //10^25
        {       0x52b7d2L, 0xdcc80cd2e4000000L  },  //10^26
        {       0x33b2e3cL, 0x9fd0803ce8000000L  },  //10^27
        {       0x204fce5eL, 0x3e25026110000000L  },  //10^28
        {       0x1431e0faeL, 0x6d7217caa0000000L  },  //10^29
        {       0xc9f2c9cd0L, 0x4674edea40000000L  },  //10^30
        {       0x7e37be2022L, 0xc0914b2680000000L  },  //10^31
        {       0x4ee2d6d415bL, 0x85acef8100000000L  },  //10^32
        {       0x314dc6448d93L, 0x38c15b0a00000000L  },  //10^33
        {       0x1ed09bead87c0L, 0x378d8e6400000000L  },  //10^34
        {       0x13426172c74d82L, 0x2b878fe800000000L  },  //10^35
        {       0xc097ce7bc90715L, 0xb34b9f1000000000L  },  //10^36
        {       0x785ee10d5da46d9L, 0x00f436a000000000L  },  //10^37
        {       0x4b3b4ca85a86c47aL, 0x098a224000000000L  },  //10^38
    };
  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值