问题描述
我正在对 ClickHouse database 进行测试,以验证 Decimal 数据类型。 根据文档:
十进制参数:
P - 精度。有效范围:[1 : 76]。确定数字可以有多少个十进制数字(包括分数)。 S - 规模。有效范围:[0 : P]。确定分数可以有多少个十进制数字。 取决于 P 参数值 Decimal(P,S) 是:
- P 来自 [1 : 9] - 用于 Decimal32(S)
- P 来自 [10 : 18] - 用于 Decimal64(S)
- P 来自 [19 : 38] - 用于 Decimal128(S)
- P 来自 [39 : 76] - 用于 Decimal256(S)
我正在尝试为所有这些数据类型生成随机数。 我已经找到了一个 good answer,这就是我使用它的方式:
Decimal32:
>>> decimal.Decimal(random.randint(-2147483648,2147483647))/1000
Decimal('-47484.47')
Decimal64:
>>> decimal.Decimal(random.randint(-9223372036854775808,9223372036854775807))/100000000000
Decimal('-62028733.96730274309')
这两个给了我预期的结果。 但是,我的 Decimal128 函数已经太长并产生错误的结果:
>>> decimal.Decimal(random.randint(-170141183460469231731687303715884105728,170141183460469231731687303715884105727))/1000000000000000000000
Decimal('149971182339396169.8957534906')
问题:
如何生成随机的 Decimal128 和 Decimal256?
请建议我应该使用什么。
解决方法
您面临的问题是精度设置不够高,无法记录您部门中的所有数字。修复它最简单的方法是提高精度(以除法和所有其他操作需要更长的时间执行为代价。默认精度设置为 28,即 28 个正确的小数位。这对于 来说已经足够了Decimal64,但对于 Decimal128 和 Decimal256
来说太少了要更新您编写的精度:
decimal.getcontext().prec = 38 # Maximum number of fractional digits in Decimal128
在此之后,您的代码应该可以工作了。当然,对于Decimal256,精度需要设置为76。