使用Sybase ASE 15.7
,我被要求评估复杂计算的可行性。实际上,计算并不复杂,但它需要处理非常大的数字并同时保持非常高的小数精度。
以下是我的约束:
DECIMAL
数字类型,我最多可以使用38位数,这意味着我可以在小数点左边只有20个。)以下是我的原型现在的样子:
CREATE PROCEDURE dbo.MyProc
(
@X DECIMAL(38,18),
@ALPHA DECIMAL(38,18),
@BETA_1 DECIMAL(38,18),
@BETA_2 DECIMAL(38,18),
@BETA_3 DECIMAL(38,18),
@BETA_4 DECIMAL(38,18),
@BETA_5 DECIMAL(38,18)
)
AS
BEGIN
DECLARE @POLY_1 DECIMAL(38,18)
SET @POLY_1 = @ALPHA
DECLARE @POLY_2 DECIMAL(38,18)
SET @POLY_2 = @BETA_1 * @X
DECLARE @POLY_3 DECIMAL(38,18)
SET @POLY_3 = @BETA_2 * POWER(@X,2.0)
DECLARE @POLY_4 DECIMAL(38,18)
SET @POLY_4 = @BETA_3 * POWER(@X,3.0)
DECLARE @POLY_5 DECIMAL(38,18)
SET @POLY_5 = @BETA_4 * POWER(@X,4.0)
DECLARE @POLY_6 DECIMAL(38,18)
SET @POLY_6 = @BETA_5 * POWER(@X,5.0)
DECLARE @POLY_SUM DECIMAL(38,18)
SET @POLY_SUM = @POLY_1 + @POLY_2 + @POLY_3 + @POLY_4 + @POLY_5 + @POLY_6
SELECT @POLY_SUM
END
GO
以下是使用实际数据的示例:
EXEC dbo.MyProc 360, 0.000000000000000000, 3.001691154643420000, -0.004000558548191020, 0.000003108186568058, 0.000000000639528525, -0.000000000000517669
上述示例查询的结果是NULL
。稍微调整一下我的程序后:
CREATE PROCEDURE dbo.MyProc
(
@X DECIMAL(38,18),
@ALPHA DECIMAL(38,18),
@BETA_1 DECIMAL(38,18),
@BETA_2 DECIMAL(38,18),
@BETA_3 DECIMAL(38,18),
@BETA_4 DECIMAL(38,18),
@BETA_5 DECIMAL(38,18)
)
AS
BEGIN
DECLARE @POLY_1 DECIMAL(38,18)
SET @POLY_1 = @ALPHA
DECLARE @POLY_2 DECIMAL(38,18)
SET @POLY_2 = @BETA_1 * @X
DECLARE @POLY_3 DECIMAL(38,18)
SET @POLY_3 = @BETA_2 * CONVERT(DECIMAL(38,18),POWER(@X,2.0))
DECLARE @POLY_4 DECIMAL(38,18)
SET @POLY_4 = @BETA_3 * CONVERT(DECIMAL(38,18),POWER(@X,3.0))
DECLARE @POLY_5 DECIMAL(38,18)
SET @POLY_5 = @BETA_4 * CONVERT(DECIMAL(38,18),POWER(@X,4.0))
DECLARE @POLY_6 DECIMAL(38,18)
SET @POLY_6 = @BETA_5 * CONVERT(DECIMAL(38,18),POWER(@X,5.0))
DECLARE @POLY_SUM DECIMAL(38,18)
SET @POLY_SUM = @POLY_1 + @POLY_2 + @POLY_3 + @POLY_4 + @POLY_5 + @POLY_6
SELECT @POLY_SUM
END
GO
我终于设法获得了正确的结果:714.763457289478656
。
现在,真正的问题是存储过程的第一个参数变量X
的范围从最小1
到最大10000000
。一旦X
值增加到他的最大值,我开始得到算术溢出问题,因为...... 500000^4
(只是我范围内的随机值)增长到{{1没有数字类型可以存储这么大的值。
我几乎阅读了每篇博客文章/关于如何处理非常大数字的SO帖子/教程是SQL,但我发现没有什么可以帮助我。实际上......这个问题有解决方案吗?如果是的话,哪一个?
我正在考虑所有可能的方法......将31250000000000000000000000000
除以X
并将所有测试值乘以相同的值(这只会延迟失败时刻),使用对数基数(不可能,因为贝塔可以是负数),分解函数以减少指数......我不知道...