【问题标题】:SQL Server - Strange round behaviour when using variable vs just valueSQL Server - 使用变量与仅值时的奇怪循环行为
【发布时间】:2022-01-15 05:22:06
【问题描述】:

在分割存储在变量中的浮点数与仅使用值时,我在 SQL Server 中遇到了这个奇怪的问题。

案例如下:

DECLARE @FLOAT FLOAT = 6.80
print ROUND(@FLOAT / 2, 2, 0);  
print ROUND(@FLOAT / 2, 2, 1);  

打印出来:

3.4
3.39

截断值的第二个 ROUND 给出了错误的值。它应该是 3.4 而不是 3.39。

但是当我使用没有变量的值时,它可以正常工作:

print ROUND(6.80 / 2, 2, 0);  
print ROUND(6.80 / 2, 2, 1);  

打印出来:

3.400000
3.400000

谁能帮我理解这个问题? 提前致谢。

【问题讨论】:

  • 一点也不奇怪,您使用float 作为第一个表达式,使用decimal 作为第二个表达式,您应该期待这样的行为。以 2 为基数和以 10 为基数的数字行为完全不同。
  • 感谢您的快速评论。很抱歉,但我认为我不明白您所说的与浮点数相关的“以 2 为基数和以 10 为基数的数字行为完全不同”是什么意思。
  • Base 2 或二进制数与 Base 10 或十进制数。非整数值通常无法与前者准确存储。例如,阅读here

标签: sql sql-server floating-point rounding


【解决方案1】:

这种行为是预期的。在第一个表达式中,您使用的是float,而在后一个表达式中是decimal。这两种数据类型非常不同。前者是 Base 2 值,后者是 Base 10。

6.80 无法使用 Base 2 精确存储,因此它的 实际 值更接近于值 6.79999999999999982236431605997495353221893310546875。如您所见,这小于6.8,因此当您将该数字除以2时,您会得到一个略小于3.40的数字,可能是@987654328 @。

结果ROUND 正确舍入数字,因为上述值舍入为 2 位 3.39 不是 @ 987654331@.

对于文字,6.80 是精确表示的,6.80 / 2 (3.40) 也是如此,所以当您再次将该数字四舍五入到小数点后 2 位时,您仍然会得到 3.40

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多