为什么当我运行下面的代码时,它应该在表中插入值122387593.6,它是否插入值122387593.59999999?
我已跟踪.net发出的调用,可以看到该值是以122387593.59999999传递给SQL的,但调试参数值时返回为122387593.6?!
我无法理解为什么.NET会这样做 - 非常感谢任何帮助。
---SQL Code
CREATE TABLE [dbo].[tblNum](
[Num] [numeric](28, 8) NOT NULL
) ON [PRIMARY]
CREATE PROCEDURE spNumInsert (@Num numeric(28,8))
AS
BEGIN
INSERT INTO tblNum VALUES(@Num)
END
GO
--.NET Code
Dim a = Double.Parse("122387593.6", Globalization.CultureInfo.InvariantCulture)
Dim con As SqlConnection = New SqlConnection("Server=server;Database=database;Trusted_Connection=True;")
Dim com As SqlCommand = New SqlCommand("spNumInsert", con)
com.CommandType = CommandType.StoredProcedure
com.Parameters.Add(New SqlParameter("@Num", a))
con.Open()
com.ExecuteNonQuery()
con.Close()
con.Dispose()
答案 0 :(得分:10)
double
表示IEEE754。 IEEE754 无法表达每个值。 IEEE754中很可能122387593.6
不存在,122387593.59999999
是最接近的近似值。
如果你需要与我们肉食人类倾向于同意的价值相匹配的“精确”近似值(注意术语中的矛盾),那么你应该使用decimal
,而不是double
。
要明确:decimal
和double
都被迫近似 - 只有这么多你才能将这样一系列可能的值拟合成有限字节。但它们近似的方式是不同的。 decimal
适用于金钱等离散测量; double
适用于连续测量。
答案 1 :(得分:3)
请勿使用Double.Parse
。您需要使用Decimal
。
您的对象a
已经是122387593.59999999,因为这是122387593.6必须在浮点标准中表示的,这是双倍的。
答案 2 :(得分:1)
问题在于.NET的精度为double。如果您在此行之后结帐变量a
Dim a = Double.Parse("122387593.6", Globalization.CultureInfo.InvariantCulture)
你会注意到它已经错了。您可以尝试使用decimal
更精确。
答案 3 :(得分:-3)
使用功能
ROUND ( numeric_expression , length [ ,function ] )