专栏名称: 爬虫俱乐部
Stata技术控,编程技术咨询,数据讨论与分享,编程和实证培训。
目录
相关文章推荐
昆明信息港  ·  今天12点开抢!加油券第二期来啦! ·  8 小时前  
微信公开课  ·  微信5月功能合集 ·  昨天  
云南网  ·  白象致歉! ·  昨天  
昆明信息港  ·  出行火热!超6.5亿人次! ·  2 天前  
51好读  ›  专栏  ›  爬虫俱乐部

decimal 进行无误差浮点数计算

爬虫俱乐部  · 公众号  ·  · 2018-07-24 10:24

正文

请到「今天看啥」查看全文



什么是浮点数呢?通俗来说就是 小数 。我们知道,二进制是很方便地表示十进制整数的,如整数 25 = 16 + 8 + 1 . 因此25的 二进制 表示就是 00011001 ,只要给的二进制位数足够多,就可以精确地表示任意一个整数。对于一个 byte 的空间 (8个二进制位 ),可以表示 0 - 255 的整数 (00000000 - 11111111)

但是小数怎么用二进制表示呢?————将小数部分与整数部分分别表示,我们假设用 2个byte 来储存一个小数 7.375 ,则 整数 部分表示为 00000111 (1+2+4,二进制的三个1分别表示2的二次方、一次方、零次方), 小数 部分表示为 01100000 (0.25 + 0.125,二进制的两个1分别表示2的负二次方和负三次方,相加得0.375),因此该数字表示为 00000111 01100000.

看起来一切都很完美,但一个坏消息是,这种表示方法,无法精确地表示某些十进制小数,如 0.1就无法被二进制精确表示 ,用来存储小数部分的空间越大,则表示得越精确,但永远无法准确表示。

这样一来似乎问题变得“ 无解 ”,我们无法精确计算一个数字的原因竟然是,计算机无法精确表示1.1这样的浮点数,这一问题在计算精度要求比较低时,尚不会有严重问题,但当 某些特殊环境下 ,如计算一个每月 持续上浮10% 的股票时,这一误差会被迅速放大,给模型带来 巨大 的困扰。


decimal:十进制数计算模块


令人 惊喜 的是,Python提供了专门的模块来解决这个问题,即 decimal 模块, decimal的含义是十进制 ,顾名思义,decimal模块用于在计算机中存储“ 真正的十进制数 ”。decimal模块解决浮点数表达的思路是, 抛弃二进制 计算方式, 直接以十进制 的方式直接进行计算,将小数以“字符串”的形式存储起来,当使用该“字符串”进行计算时,得到的依然是“ 字符串 ”( 也就是Decimal类的实例 )。但悲喜总是相伴而生,当我们在电脑上使用十进制方法进行计算时,其 速度 自然远远 不如 二进制数的计算速度。但如果遇到对计算精度要求非常高的需求时,必要的效率上的牺牲是非常值得的。


使用范例


1. 生成decimal类型的小数

In [1]: import decimal

In [2]: a = decimal.Decimal('1.1')

In [3]: a * a
Out[3]: Decimal('1.21')

我们使用 decimal 模块中的类Decimal初始化了 1.1 这个小数,并生成名为 a 的Decimal对象,接着输出 a * a ,返回的依旧是一个Decimal对象,值为 1.21

2. 特殊值表示

除了普通的数字值,Decimal 还可以表示很多 特殊值 ,包括 正负无穷大值 、“ 不是一个数 ”(NaN)

In [11]: decimal.Decimal('NaN') ,decimal.Decimal('-NaN')
Out[11]: (Decimal('NaN'), Decimal('-NaN'))

In [12]: decimal.Decimal('Infinity'






请到「今天看啥」查看全文