SQL 服务器 - 使用 FLOAT 值更新 INT 字段时出错。价值变化
SQL Server - Error when update a INT field with a FLOAT value. Value change
我在用浮点值更新整型变量时遇到问题。值“100”在更新时更改为“99”。
DECLARE @intResultado INTEGER=NULL
DECLARE @dblResultado FLOAT=NULL
DECLARE @dblValorMercado FLOAT =15700123654.8047
DECLARE @intCambioTasaInteres INTEGER=100
SET @intResultado=SUM(@dblValorMercado * @intCambioTasaInteres) / SUM(CASE WHEN @dblValorMercado = 0 THEN NULL ELSE @dblValorMercado END)
SET @dblResultado=SUM(@dblValorMercado * @intCambioTasaInteres) / SUM(CASE WHEN @dblValorMercado = 0 THEN NULL ELSE @dblValorMercado END)
SELECT '1. Operation result =' AS [Result], SUM(@dblValorMercado * @intCambioTasaInteres) / SUM(CASE WHEN @dblValorMercado = 0 THEN NULL ELSE @dblValorMercado END) AS [Operation], 'GOOD' AS EVAL
UNION
SELECT '2. Integer operation result =',@intResultado, 'BAD'
UNION
SELECT '3. Float operation result = ',@dblResultado, 'GOOD'
这是结果:
Result Operation EVAL
------------------------------ ---------------------- ----
1. Original operation result = 100 GOOD
2. Integer operation result = 99 BAD
3. Float operation result = 100 GOOD
(3 row(s) affected)
进行的计算是 "sum of weighted averages",在本例中仅对应 1 个值(在本例中为 100),但也可能是 n 个值,用于执行加权平均值的总和。
这个问题可以通过将 INT 变量更改为 FLOAT 变量来解决,但这不是我们的想法。但是要检测为什么更新时的值100变成了值99以及如何用INT变量更新正确的值100。
谢谢
我怀疑 SQL 引擎正在尝试在完成算术之前进行转换。请参阅 https://www.red-gate.com/simple-talk/sql/t-sql-programming/how-to-get-sql-server-data-conversion-horribly-wrong/ 第 3 节:假设所有数字生而平等
请注意,当他将 DECIMAL 分配给 INT 变量时,它是 FLOOR 的值。
这两个语句也产生 99:
SELECT CONVERT( INT, (@dblValorMercado * @intCambioTasaInteres) / @dblValorMercado )
SELECT FLOOR( (@dblValorMercado * @intCambioTasaInteres) / @dblValorMercado )
而正如您所指出的,下面的结果是 100:
SELECT (@dblValorMercado * @intCambioTasaInteres) / @dblValorMercado
在 C# 中,将 float 转换为 int 存在类似的问题。 (https://answers.unity.com/questions/701483/float-to-int-conversion-using-int-gives-wrong-answ.html)
我在用浮点值更新整型变量时遇到问题。值“100”在更新时更改为“99”。
DECLARE @intResultado INTEGER=NULL
DECLARE @dblResultado FLOAT=NULL
DECLARE @dblValorMercado FLOAT =15700123654.8047
DECLARE @intCambioTasaInteres INTEGER=100
SET @intResultado=SUM(@dblValorMercado * @intCambioTasaInteres) / SUM(CASE WHEN @dblValorMercado = 0 THEN NULL ELSE @dblValorMercado END)
SET @dblResultado=SUM(@dblValorMercado * @intCambioTasaInteres) / SUM(CASE WHEN @dblValorMercado = 0 THEN NULL ELSE @dblValorMercado END)
SELECT '1. Operation result =' AS [Result], SUM(@dblValorMercado * @intCambioTasaInteres) / SUM(CASE WHEN @dblValorMercado = 0 THEN NULL ELSE @dblValorMercado END) AS [Operation], 'GOOD' AS EVAL
UNION
SELECT '2. Integer operation result =',@intResultado, 'BAD'
UNION
SELECT '3. Float operation result = ',@dblResultado, 'GOOD'
这是结果:
Result Operation EVAL
------------------------------ ---------------------- ----
1. Original operation result = 100 GOOD
2. Integer operation result = 99 BAD
3. Float operation result = 100 GOOD
(3 row(s) affected)
进行的计算是 "sum of weighted averages",在本例中仅对应 1 个值(在本例中为 100),但也可能是 n 个值,用于执行加权平均值的总和。
这个问题可以通过将 INT 变量更改为 FLOAT 变量来解决,但这不是我们的想法。但是要检测为什么更新时的值100变成了值99以及如何用INT变量更新正确的值100。
谢谢
我怀疑 SQL 引擎正在尝试在完成算术之前进行转换。请参阅 https://www.red-gate.com/simple-talk/sql/t-sql-programming/how-to-get-sql-server-data-conversion-horribly-wrong/ 第 3 节:假设所有数字生而平等
请注意,当他将 DECIMAL 分配给 INT 变量时,它是 FLOOR 的值。
这两个语句也产生 99:
SELECT CONVERT( INT, (@dblValorMercado * @intCambioTasaInteres) / @dblValorMercado )
SELECT FLOOR( (@dblValorMercado * @intCambioTasaInteres) / @dblValorMercado )
而正如您所指出的,下面的结果是 100:
SELECT (@dblValorMercado * @intCambioTasaInteres) / @dblValorMercado
在 C# 中,将 float 转换为 int 存在类似的问题。 (https://answers.unity.com/questions/701483/float-to-int-conversion-using-int-gives-wrong-answ.html)