【问题标题】:Is there a workaround when an underflow error occurs in PostgreSQL?在 PostgreSQL 中发生下溢错误时是否有解决方法?
【发布时间】:2015-12-03 20:17:28
【问题描述】:

我有一个表格,每行包含以下公式中的指数曲线的 a、b 和 c 参数:

a*exp(-b*x)+c

所有列都是双精度类型。 我希望以 x 的特定值对每条曲线进行采样,并将其值记录在新列中。但是,这样做会导致下溢错误。

>update curve_by_wkt set samplepoint05 = a*exp(-b*0.05)+c;
ERROR:  value out of range: underflow

我无法手动检查 a、b、c 的哪些值导致计算失败。我所知道的是,不需要极高的精度,超出一定范围的值可能无关紧要。

考虑到我对精度的漠视,我想知道是否有任何方法可以完成计算。

谢谢

【问题讨论】:

标签: postgresql underflow


【解决方案1】:

创建一个函数并捕获异常。您可以提出自己的错误消息:

create or replace function calculate_with_error
    (a double precision, b double precision, c double precision, x double precision)
returns double precision language plpgsql as $$
begin
    return a * exp(-b * x) + c;
    exception when numeric_value_out_of_range then 
        raise exception 'Value out of range for a = % b= % c= % x= %', a, b, c, x;
end $$;

select calculate_with_error(1, 1, 0, 10000);

ERROR:  Value out of range for a = 1 b= 1 c= 0 x= 10000

或设置一些默认值:

create or replace function calculate_with_default
    (a double precision, b double precision, c double precision, x double precision)
returns double precision language plpgsql as $$
begin
    return a * exp(-b * x) + c;
    exception when numeric_value_out_of_range then 
        return 0;
end $$;

select calculate_with_default(1, 1, 0, 10000);

 calculate_with_default 
------------------------
                      0
(1 row)

用法:

update curve_by_wkt 
set samplepoint05 = calculate_with_error(a, b, c, 0.05);

【讨论】:

    【解决方案2】:

    更好的解决方案(很可能)是只使用greatest 函数来设置最小值。例如,

     greatest(a*exp(-b*x)+c, -50)
    

    大多数时候 0 或任意低的数字就足够了。

    【讨论】:

    • 这没有帮助。 exp(-1000) 产生下溢错误,greatest(exp(-1000),1e-15) 也是如此。
    猜你喜欢
    • 1970-01-01
    • 2021-11-12
    • 1970-01-01
    • 2023-01-04
    • 2011-11-03
    • 2018-06-24
    • 2017-09-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多