表示范围

简介: 表示范围

大多数编程语言使用某些固定长度的比特位来表达数值。因此,数值的表示在范围精度上都是有限制的。


标准Lua 使用 64 个比特位来存储整型值,其最大值为263-1,约等于1019精简Lua 使用 32 个比特位存储整型值,其最大值约为 20亿 。数学库中的常量定义了整型值的最大值math.maxinteger )和最小值math.mininteger )。


64 位整型值中的最大值是一个很大的数值:全球财富总和(按美分计算)的数千倍和全球人口总数的数十亿倍。尽管这个数值很大,但是仍然有可能发生溢出。当我们在整型操作时出现比 mininteger 更小或者比 maxinteger 更大的数值时,结果就会回环


在数学领域,回环的意思是结果只在 minintegermaxinteger 之间,也就是对264取模的算数结果。在计算机领域,回环的意思是丢弃最高进位。假设最高进位存在,其将是 65 个比特位,代表264。因此,忽略第 65 个比特位不会改变值对264取模的结果。


Lua 语言中,这种行为对所有涉及整型值的算术运算都是一致且可预测的,如下所示:

> math.maxinteger + 1 == math.mininteger      --> true
> math.mininteger -1 == math.maxinteger       --> true
> -math.mininteger == math.mininteger         --> true
> math.mininteger // -1 == math.mininteger    --> true


最大可以表示的整数是 0x7ff...fff ,即除最高位(符号位,零为非负数值)外其余比特位均为 1 。当我们对 0x7ff...fff1 时,其结果变为 0x800...000 ,即最小可表示的整数。最小整数比最大整数的表示幅度大 1

> math.maxinteger     --> 9223372036854775807
> 0x7fffffffffffffff  --> 9223372036854775807
> math.mininteger     --> -9223372036854775808
> 0x8000000000000000  --> -9223372036854775808


对于浮点数而言,标准Lua使用双精度。标准Lua使用 64 个比特位表示所有数值,其中 11 位为指数。双精度浮点数可以表示具有大致 16 个有效十进制位的数,范围[-10308, 10308]。精简Lua使用 32 个比特位表示单精度浮点数,大致具有 7 个有效十进制位,范围[-1038, 1038]。


双精度浮点数对于大多数实际应用而言是足够大的,但是我们必须了解精度的限制。如果我们使用十位表示一个数,那么 1/7 会被取整到 0.142857142 。如果我们使用十位计算 1/7*7 ,结果会是 0.999999994 ,而不是 1 。此外,用十进制表示的有限小数在用二进制表示时可能是无限小数。例如, 12.7-20+7.3 即便是用双精度表示也不是 0 ,这时由于 12.77.3 的二进制表示不是有限小数。


由于整型值和浮点型值的表示范围不同,因此当超过他们的表示范围时,整型值和浮点型值的算数运算会产生不同的结果:

> math.maxinteger + 2       --> -9223372036854775807
> math.maxinteger + 2.0     --> 9.2233720368548e+18


在上例中,两个结果从数学的角度看都是错误的,而且他们的错误方式不同。第一行对最大可表示整数进行了整型求和,结果发生了回环。第二行对最大可表示整数进行了浮点型求和,结果被取整成了一个近似值,这可以通过如下的比较运算证明:

> math.maxinteger + 2.0 == math.maxinteger + 1.0      --> true


尽管每一种表示都有其优势,但是只有浮点型才能表示小数。浮点型的值可以表示很大范围,但是浮点型能够表示的整数范围被精确地限制在[-253, 253]之间。在这个范围内,我们基本可以忽略整型和浮点型的区别;超出这个范围后,我们则应该谨慎地思考所使用的表示方式。

目录
相关文章
|
存储 缓存 NoSQL
Redis Cluster 为什么选哈希槽不选一致性哈希?
Redis相信大家都很熟悉,它是我们常用的分布式缓存中间件之一。那么大家对于Redis Cluster集群是否熟悉呢?在Redis集群中并没有使用一致性hash, 而是引入了 **哈希槽**的概念,为什么选哈希槽不选一致性哈希。
3837 1
|
网络安全 开发工具 数据安全/隐私保护
解决 Enter passphrase for key ‘/Users/dzm/.ssh/id_rsa‘:
解决 Enter passphrase for key ‘/Users/dzm/.ssh/id_rsa‘:
1664 0
|
5月前
|
Go 网络安全 开发工具
终极攻略!go get命令使用教程
终极攻略!go get命令使用教程
1572 0
|
11月前
|
算法
几款主流的压缩算法对比Zlib,snappy,lz4
几款主流的压缩算法对比Zlib,snappy,lz4
713 0
|
机器学习/深度学习 NoSQL 关系型数据库
Redis系列七 - 实现排行榜功能
Redis系列七 - 实现排行榜功能
293 0
|
NoSQL 算法 架构师
Redis分布式锁的原理以及如何续期
Redis分布式锁的原理以及如何续期
|
消息中间件 分布式计算 NoSQL
MongoDB适用场景
MongoDB适用场景
|
算法 C++
LeetCode刷题day27
LeetCode刷题day27
|
消息中间件 JSON 安全
Go 第三方 log 库之 logrus 使用
Go 第三方 log 库之 logrus 使用
1019 0