我正在玩pg_size_pretty(),我发现当我传递一个很大的值时,它会开始返回负值.这是我的测试:
select pg_size_pretty(9223370000000000000); -- "8388606 TB"
select pg_size_pretty(9223371000000000000); -- "8388607 TB"
select pg_size_pretty(9223372000000000000); -- "-8388607 TB"
Run Code Online (Sandbox Code Playgroud)
你能解释一下为什么吗?谢谢.
最高签名的64位int是922337203685477587.这只是比有问题的数字略多一点.当然在某处有溢出pg_size_pretty.
基于注释中提到的代码,pg_size_pretty尝试对数字进行舍入,并使用大于最大有符号64位int的中间值来实现.9223372000000000000 + 1024*1024*1024*1024/2 = 9223372549755813888,大于922337203685477587.
更新:添加第二段并澄清溢出不在调用者中.
你没有溢出,pg_size_pretty溢出来了.该pg_size_pretty函数应该采取bigint:
pg_size_pretty(bigint)
text
将大小以字节为单位转换为具有大小单位的人类可读格式
并9223372000000000000 < 9223372036854775808因此9223372000000000000是完全有效的bigint和pg_size_pretty应该做正确的事吧.您应该向PostgreSQL人员报告错误并赢得赞誉.
更新:检查PostgreSQL源代码(感谢Jeremiah Peschka提供的链接)向我们展示了bug的位置:
491 else
492 {
493 mult *= 1024;
494 snprintf(buf, sizeof(buf), INT64_FORMAT " TB",
495 (size + mult / 2) / mult); /* OVERFLOW! */
496 }
Run Code Online (Sandbox Code Playgroud)
如果size接近极限int64,那么mult/2在下面的除法之前加上它就会溢出,mult可以把它带回范围.
| 归档时间: |
|
| 查看次数: |
431 次 |
| 最近记录: |