Postgresql四舍五入至有效数字

xdyibdwo  于 2023-01-08  发布在  PostgreSQL
关注(0)|答案(3)|浏览(254)

我试过这个blog中的有效数字查询(https://www.garysieling.com/blog/postgres-significant-figures-pg_size_pretty)。
但是上面好像有固定的小数位。

SELECT FLOOR(5.4321/(10 ^ FLOOR(log(5.4321)-1))) * (10 ^ FLOOR(log(5.4321)-1))

上述查询的结果是5.4。如何实现查询以创建这些结果?

number | sigfig
5.4321 | 5.43
10.987 | 10.9
550.75 | 550
9850.5 | 9850
ect

谢谢兄弟们的帮助!

ddarikpa

ddarikpa1#

您可以使用以下函数舍入到有效位数:

CREATE OR REPLACE FUNCTION sig_digits(n anyelement, digits int) 
RETURNS numeric
AS $$
    SELECT CASE
        WHEN n=0 THEN 0
        ELSE round(n, digits - 1 - floor(log(abs(n)))::int)
    END
$$ LANGUAGE sql IMMUTABLE STRICT;

与Laurenz的回答相比,这有以下不同之处:

  • 对结果进行四舍五入,而不是取整(例如sig_digits(15, 1)20,而不是10
  • 该函数接受任意类型作为第一个参数(如float),而不仅仅是numeric
  • 它的速度更快,因为它尽可能避免在数字上调用log(这很慢),并且只调用log一次
  • 它返回漂亮的结果,而没有不必要的尾随零。
  • 它处理零输入
qf9go6mv

qf9go6mv2#

为了提供这个问题的更一般的答案,我建议您使用以下函数,其中有效位数是可变的:

CREATE FUNCTION significant_digits(n numeric, digits integer) RETURNS numeric
   LANGUAGE sql IMMUTABLE STRICT AS
'SELECT floor(n / (10 ^ floor(log(n) - digits + 1)))
        * (10 ^ floor(log(n) - digits + 1))';

然后,您将得到以下内容:

test=> SELECT significant_digits(5.4321, 3);
 significant_digits 
--------------------
 5.4300000000000000
(1 row)

test=> SELECT significant_digits(9.87654, 3);
 significant_digits 
--------------------
 9.8700000000000000
(1 row)

请注意,公式并不像博客文章所声称的那样是“舍入”,而是“截断”。

jjhzyzn0

jjhzyzn03#

将计数(状态)四舍五入到最高有效位的示例:

select count(status),
  round(count(status) / pow(10, trunc(log(count(status))) ) ) * pow(10, trunc(log(count(status))) ) 
  from  some_table;

Eg. 1234 => 1000
    987  => 900

相关问题