3

我在玩 pg_size_pretty() 并且我发现当我传递一个很大的值时它开始返回负值。这是我的测试:

select pg_size_pretty(9223370000000000000); -- "8388606 TB"
select pg_size_pretty(9223371000000000000); -- "8388607 TB"
select pg_size_pretty(9223372000000000000); -- "-8388607 TB"

你能解释一下为什么吗?谢谢。

4

2 回答 2

5

最高的有符号 64 位整数是 922337203685477587。这比所讨论的数字多一点点。肯定有在某处溢出pg_size_pretty

根据评论中提到的代码,pg_size_pretty正在尝试对数字进行舍入,并使用大于最大有符号 64 位 int 的中间值进行舍入。9223372000000000000 + 1024*1024*1024*1024/2 = 9223372549755813888,大于922337203685477587。

更新:添加了第二段并澄清溢出不在调用者中。

于 2011-04-24T01:42:51.670 回答
5

你不是溢出,pg_size_pretty是溢出。该pg_size_pretty功能应该采用bigint

pg_size_pretty(bigint)
text
将字节大小转换为具有大小单位的人类可读格式

所以是完全有效的,应该用它做正确的事9223372000000000000 < 9223372036854775808。您应该向 PostgreSQL 人员报告错误并赢得荣誉。9223372000000000000bigintpg_size_pretty

更新:检查 PostgreSQL 源代码(感谢 Jeremiah Peschka 提供链接)向我们展示了错误所在:

491                 else
492                 {
493                     mult *= 1024;
494                     snprintf(buf, sizeof(buf), INT64_FORMAT " TB",
495                              (size + mult / 2) / mult); /* OVERFLOW! */
496                 }

如果size接近 的限制,那么在接下来的除以将其带回范围之前int64,添加它会溢出。mult/2mult

于 2011-04-24T02:02:54.043 回答