每天进步一点点:Python 中int64_t的最大值?

in #cn5 years ago

在测试HIVE API的时候,发现要想使其中的一个API按着预想中的情况正确工作,需要传入int64_t类型的最大值,你要说什么8位、16位的最大值,我也许张口就来,可以64位我的大脑也处理不过来啊。


(图源 :pixabay)

基本原理

HIVE代码中直接用的是std::numeric_limits< int64_t >::max(),我也没法直接引用呀。

那64位最大值是多少呢?我们知道,计算机中的数都是以二进制形式表示,所谓多少位就是多少个0和1,比如64位就是64个0、1组合。

有符号数最高位用来表示符号位,符号位为0表示正数,符号位为1表示负数,其它数位用补码的形式表示:

正数的补码就是其二进制表示,与原码相同;负数的补码就是除符号位外的所有位取反后加1。

代码计算

知道了这些,那么求不同位数的数的最大正值就很容易了,比如我可以根据上述信息写出如下函数:

image.png

其实就是计算二进制函数的10进制值,因为正数补码和源码相同,那么int64_t最大值其实就是63个1组成的二进制数

我们来测试并计算一下:

image.png

看来9223372036854775807就是我们想要的结果。

使用ctypes

为了计算一个数值,写了一堆垃圾代码,我觉得我有点傻,那是不是有更简便的方法呢?我找到一种也许不算是简便方法的方法,那就是使用ctypes

ctypes能做很多事情,不过我想让它做的就是在python中使用c语言的类型,比如int64,而我们根据上述分析不难得出,int64最大值就是uint64最大值减1再除以2。

所以我们可以利用如下代码计算int64的最大值:

image.png

对比不难发现,和我们之前计算的结果完全一致。

移位计算

其实还有一种更简单的方法就是移位计算法,int64的最大值是63个1组成的2进制数,那么怎么能得到这个二进制数呢?

我们知道1个1组成的2进制数,是可以通过二进制数10减去二进制数1来获取,那么63个1组成的二进制数,其实也可以用10000(63个零)组成的64位二进制数减1来获取,而1后边63个零,就是把1左移了63位。

代码也超级简单:

image.png

到底用啥?

尽管我制造出三种超级复杂的计算方法,但是我觉得很傻,不就是一个数嘛,直接引用9223372036854775807就好了呗?

可是在代码中引用这个数我又觉得很不优雅,哪怕我可以做类似如下定义:

MAX_INT64_VALUE = 9223372036854775807

我估计以后我会忍不住问自己,这个9223372036854775807哪里来的呢?

想了好久之后突然想起来,我是不是太傻了,十六进制数就是二进制数的便于阅读的表示嘛,那么INT64的最大值,那不就是0x7FFFFFFFFFFFFFFF嘛(最高位不等于1),所以代码中直接用以下定义即可:

MAX_INT64_VALUE = 0x7FFFFFFFFFFFFFFF

既含义明确,又不会有疑问,看起来又很优雅。

补充

网上还有代码计算int类型最大值,使用sys.max_size,在64位主机上代码可以得出正确的值。

但是在32位系统上,算出的值就是int32_t的最大值了。

image.png

所以在我们的程序中使用这种对系统依赖程度高的代码,是行不通的。

相关链接

Coin Marketplace

STEEM 0.25
TRX 0.20
JST 0.038
BTC 95561.42
ETH 3560.31
USDT 1.00
SBD 3.76