4

我对 POWER/LOG 的问题是,尽管它们似乎适应了您发送的数据类型(输出变量类型与第一个变量的类型匹配),但精度似乎停止接近浮点数的限制,导致输出不正确。例子:

DECLARE @ten numeric(18,4) = 10
declare @num numeric(18,4) = 234567890
SELECT power(@ten,log(@num,@ten))

输出 = 234567890.0000 这是正确的

但是,如果我们提高精度,如下:

DECLARE @ten numeric(18,6) = 10
declare @num numeric(18,6) = 234567890
SELECT power(@ten,log(@num,@ten))

输出 = 234567889.999999 这是不正确的,但四舍五入可以解决它(?)

最后,如果将精度更改为 Numeric(18,9) 之类的值,问题会变得更糟:

DECLARE @ten numeric(18,9) = 10
declare @num numeric(18,9) = 234567890
SELECT power(@ten,log(@num,@ten))

输出 = 234567889.999999310 这是不正确的,四舍五入无法解决它。

我假设问题是虽然 POWER 和 Log 函数可以接受非常精确的数据类型,但它们的工作变量必须是浮点类型吗?有没有人有这方面的经验,或者有解决它的经验?

4

2 回答 2

3

我认为问题在于 is 的返回类型,LOGFLOAT不是您传入的数据类型。FLOAT用于浮点数字数据的近似数字数据类型。浮点数据是近似的;因此,并非数据类型范围内的所有值都可以精确表示

另一方面,POWER采用浮点类型或可以隐式转换为浮点类型的表达式。作为输入,并返回取决于浮点表达式的输入类型的类型。意思是,它将返回DECIMAL的输入DECIMAL

因此,在您的情况下,LOG返回的FLOAT是传递给POWER返回的 a FLOAT,正如所引用的那样,它是不精确的。

于 2019-01-03T19:35:38.273 回答
3

可以通过两种不同的方式处理非整数:使用定点算术或浮点算术。这两种方法都会引入错误。

log()函数被记录为接受 afloat作为参数并返回 a floatpower()行为有点不同。第一个参数转换为float,但它也确定返回类型。这就是为什么回报类型的规模是由规模驱动的@ten

正在发生的一切是,您看到的是具有不同比例的完全相同的值。这个数字略有偏差并不奇怪——舍入问题是计算机上非整数运算的一个已知问题。

一点也不意外。234567889.9999993145465850830是正在产生的价值。它是 SQL Server 可以得出的最接近实际答案的结果——并且对于大多数工作来说足够接近。

于 2019-01-03T19:37:19.207 回答