2010-12-14 85 views
2

跨越一個有趣的就來了:隱式轉換和舍入

declare @test as int 
set @test = 47 

select @test * 4.333 

回報203.651

declare @test as int 
set @test = 47 

declare @out as int 
set @out = (select @test * 4.333) 

select @out 

收益203

declare @test as int 
set @test = 47 

declare @out as int 
set @out = round((select @test * 4.333),0) 

select @out 

收益204

現在我知道爲什麼它這樣做。因爲有一個從小數到int的隱式轉換,所以小數位需要切掉(因此爲203),而如果我在隱式轉換之前舍入,我得到204.

我的問題是爲什麼當SQL Server執行一個隱含的轉換是不是也是四捨五入?我知道如果我有一個很大的數字,而且它需要存儲在一個小地方,我會做的第一件事就是圍繞它,以儘可能接近原始數字。

這對我來說似乎並不直觀。

回答

4

這讓我讀書,答案似乎是明顯不滿意,最早的SQL參考我已經能夠找到(ANSI 92可here)第號的4.4.1特性指出

每當精確的或近似 數值被分配給表示一個確切的數值的 數據項或參數, 一個 近似它的值,保留舍入或截斷後導致顯著 數字數據0被表示的類型 的目標。該值被轉換爲具有目標的精度和 比例。是否截斷或舍入的選擇是 實現定義。

這讓微軟自己選擇爲tsql實現的兩個選擇之一,爲簡單起見,我們假設他們選擇了截斷。從wikipedia article on rounding看來,這在當天並不罕見。

有趣的是,根據我發現的文檔,只有轉換爲整數會導致截斷,其他導致舍入。儘管出於一些奇怪的原因,從貨幣到整數的轉換看起來可以抵消這個趨勢,因爲它允許輪轉。

From  To  Behaviour 

numeric numeric Round 

numeric int  Truncate 

numeric money Round 

money int  Round 

money numeric Round 

float int  Truncate 

float numeric Round 

float datetime Round 

datetime int  Round 

表從here

+0

出色答卷,採取+1 – 2010-12-15 09:19:07