Reputation: 9
Could anyone explain the result of the following query? I think this is a bug in SQL Server 2014.
DECLARE @x float
SET @x=58.415
SELECT ROUND(58.415,2), ROUND(@x,2)
Upvotes: 0
Views: 473
Reputation: 43626
Because the first argument is stored as decimal(5,3):
EXEC sp_describe_first_result_set N'SELECT 58.415 x', null, 0;
You have two different codes:
DECLARE @x float
SET @x=58.415
SELECT ROUND(58.415,2), ROUND(@x,2)
GO
DECLARE @x decimal(19,3)
SET @x=58.415
SELECT ROUND(58.415,2), ROUND(@x,2)
GO
Basically, the float is
Approximate-number data types for use with floating point numeric data. Floating point data is approximate; therefore, not all values in the data type range can be represented exactly.
An improvement made by @Zohar explaining why the value is converted to decimal:
In Transact-SQL statements, a constant with a decimal point is automatically converted into a numeric data value, using the minimum precision and scale necessary. For example, the constant 12.345 is converted into a numeric value with a precision of 5 and a scale of 3
Upvotes: 3
Reputation: 520878
The explanation for what you are seeing is that floating point arithmetic is not exact in SQL Server (or in any other database or programming language). Here is what is actually happening, with the "real" value being shown for explanation:
SELECT
ROUND(58.415, 2), -- rounds UP to 58.420, this is DECIMAL(10,3), EXACT
ROUND(58.4149999999999, 2) -- rounds DOWN to 58.41
The issue here is that when you made the following variable assignment:
DECLARE @x float
SET @x = 58.415
internally, SQL Server actually stored the value as an approximation, something like 58.41499999999
. Then, when rounding to two decimal places, you were left with 58.41
.
In general, if you require exact precision, you should use an exact type. In this case, DECIMAL(10,3)
would work.
Upvotes: 1