我为什么要为浮动获得额外的小数位?

时间:2016-04-28 14:40:10

标签: c# sql-server

我创建了一个这样的表:

CREATE TABLE [dbo].[tblBar1M](
    [utcDT] [datetime2](7) NOT NULL,
    [Ticker] [text] NOT NULL,
    [FwdAdjMultiplier] [float] NULL,
    [FwdAdjOpen] [float] NULL,
    [FwdAdjHigh] [float] NULL,
    [FwdAdjLow] [float] NULL,
    [FwdAdjClose] [float] NULL,
    [ActualClose] [float] NULL,
    [ActualLastBid] [float] NULL,
    [ActualLastAsk] [float] NULL,
    [Volume] [float] NULL,
    [Seq] [float] NOT NULL,
 CONSTRAINT [PK_tblBar1M] PRIMARY KEY CLUSTERED 
(
    [Seq] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO

我创建了插入命令,如:

    commandText = "INSERT INTO BT..tblBar1M VALUES(@utcDT,@Ticker,@FwdAdjMultiplier,@FwdAdjOpen,@FwdAdjHigh,@FwdAdjLow,@FwdAdjClose,@ActualClose,@ActualLastBid,@ActualLastAsk,@Volume,@Seq)";

    cmdInsertBar1M = new SqlCommand(commandText, conn);
    cmdInsertBar1M.Parameters.Add("@utcDT", SqlDbType.DateTime2);
    cmdInsertBar1M.Parameters.Add("@Ticker", SqlDbType.NVarChar);
    cmdInsertBar1M.Parameters.Add("@Seq", SqlDbType.Float);
    cmdInsertBar1M.Parameters.Add("@FwdAdjMultiplier", SqlDbType.Float);
    cmdInsertBar1M.Parameters.Add("@FwdAdjOpen", SqlDbType.Float);
    cmdInsertBar1M.Parameters.Add("@FwdAdjHigh", SqlDbType.Float);
    cmdInsertBar1M.Parameters.Add("@FwdAdjLow", SqlDbType.Float);
    cmdInsertBar1M.Parameters.Add("@FwdAdjClose", SqlDbType.Float);
    cmdInsertBar1M.Parameters.Add("@ActualClose", SqlDbType.Float);
    cmdInsertBar1M.Parameters.Add("@ActualLastBid", SqlDbType.Float);
    cmdInsertBar1M.Parameters.Add("@ActualLastAsk", SqlDbType.Float);
    cmdInsertBar1M.Parameters.Add("@Volume", SqlDbType.Float);

我填写参数:

 double FwdAdjMultiplier = 1.25;
double baropenMid = 0.727735

cmdInsertBar1M.Parameters["@FwdAdjOpen"].Value = (float)Math.Round( baropenMid * FwdAdjMultiplier,6);

float f = (float)Math.Round(baropenMid * FwdAdjMultiplier, 6);
//f = 909.668762

正如你在评论中看到的那样,VS检查f有6 DP。但是在SSMS中插入表后,FwdAdjOpen(由***包围)有更多的DP。

为什么?

utcDT   Ticker  FwdAdjMultiplier    FwdAdjOpen  FwdAdjHigh  FwdAdjLow   FwdAdjClose ActualClose ActualLastBid   ActualLastAsk   Volume  Seq
2016-04-28 14:23:00.5885822 GL  1.25    ***909.668762207031***  909.825012207031    904.681274414063    906.150024414063    724.919982910156    724.640014648438    725.200012207031    509600  6

2 个答案:

答案 0 :(得分:3)

T-SQL FLOAT是双精度。 C#float是单精度的。在T-SQL中C#调用floatREAL。你得到的是有效的(double) 909.668762f

如果你想要额外的精度,可以在C#中使用double,如果不需要,可以在SQL Server中使用REAL。见Books Online

答案 1 :(得分:0)

Float具有固有的精确错误,你不能代表一个具体的值(除非它完全适合浮点表示的值),因此,即使你对浮点数进行舍入,它的不正确值也会有所不同,因为数据库的最终值有更多的小数。

这可以为您提供有关浮动上的精确错误的更多详细信息:Floating point inaccuracy examples