2014-10-02 62 views
1

任何人都可以在SQL Server中解釋以下結果嗎?我很難過。SQL Server奇怪上限()行爲

declare @mynum float = 8.31 

select ceiling(@mynum*100) 

結果831

declare @mynum float = 8.21 

select ceiling(@mynum*100) 

結果822

我測試數字的整個範圍(SQL Server 2012)。有些增加而其他人保持不變。我不知道爲什麼天花板會以不同的方式處理其中一些問題。從float更改爲decimal(18,5)似乎解決了這個問題,但我很謹慎,可能會有其他影響,因此我錯過了。任何解釋都會有所幫助。

+1

你爲什麼使用浮動?我不知道切換到十進制的任何影響,除非你必須輸入更多,並且會有更多的可預測的準確性。去做就對了。請參閱[本文](http://databases.aspfaq.com/database/what-datatype-should-i-use-for-numeric-columns.html),[本文](http://classicasp.aspfaq。 com/general/why-does-3-2-1-5-4-7000000000000002.html),[本文](http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/12/bad-習慣性地使用錯誤的數據類型.aspx)和[本問答](http://stackoverflow.com/q/1355418/61305)。 – 2014-10-02 16:41:40

+0

Thx爲物品。 – TEIHelp 2014-10-02 17:45:05

回答

3

我認爲這被稱爲浮點精度。你可以在幾乎所有的編程語言和數據庫中找到它。這是因爲數據僅以某種精度存儲,事實上,您設置爲8.31的數據可能不是8.31,而是例如8.31631312381813,並且在將其與ceil相乘時,可能會導致出現不同的值。

SQL server documentation page你可以閱讀:

使用近似數數據類型的浮點數字數據。浮點數據是近似的;因此,數據類型範圍中的所有值都不能完全表示。

在其他數據庫系統中存在同樣的問題。例如,在mysql website處,您可以閱讀:

浮點數有時會造成混淆,因爲它們是近似值而不是以精確值存儲。寫入SQL語句中的浮點值可能與內部表示的值不同。嘗試將浮點值作爲比較對待可能會導致問題。他們也受到平臺或實施依賴關係的影響。 FLOAT和DOUBLE數據類型受這些問題影響。對於DECIMAL列,MySQL執行的操作精度爲65位十進制數,這應該解決最常見的不準確問題。

+0

@Lasse不同的數字會以不同的方式表示爲float。如果8.31實際上被表示爲8.3100000000000001,那麼你乘以831.000000000001,那麼CEILING(831.0000000000001)是什麼? 832.如果8.21被表示爲8.209999999999 ...等等。 – 2014-10-02 16:45:05

+0

您可能需要[SQL Server文檔](http://msdn.microsoft.com/en-us/library/ms173773.aspx)中的此引用,而不是MySQL文檔中的任何內容:'大概數字數據類型與浮點數字數據一起使用。浮點數據是近似的;因此,並非數據類型範圍中的所有值都可以精確表示。' – 2014-10-02 16:46:52

+0

@Lasse很棒,如果您總是處理值100。 – 2014-10-02 16:54:35

0

浮點數不是100%準確的。像MarcinNabiałek寫的8.31你看到的可能是其他東西,如8.310000000001。有關浮點精度問題的一些有趣閱讀,請參閱here

解決方案是不使用浮點數數據類型,除非你真的必須。您應該使用DECIMALMONEY數據類型。

如果你真的必須使用浮點數據類型,那麼你可以添加或每floorceiling或比較操作之前減去一個很小的值(精度thresold或小量),以獲得您想要的精確度。如果你有很多浮點操作,那麼編寫你自己的floating point comparison functions可能是值得的。