在 PostgreSQL 中发生下溢错误时是否有解决方法?

Is there a workaround when an underflow error occurs in PostgreSQL?

我有一个 table 在每一行中包含以下公式中指数曲线的 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 的哪些值导致计算失败。我所知道的是不需要极高的精度,并且特定范围之外的值可能无关紧要。

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

谢谢

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

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);

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

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

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