tags:

views:

305

answers:

5

I am trying to round to 3 decimal places from two variables of type money in SQL Server 2008.

DECLARE @Val1 money = 554.5344
DECLARE @Val2 money = 84020.37
DECLARE @Result decimal(6,5) = @Val1/@Val2 *100
SELECT @Result

The result above is 0.65. With a calculator it is 0.65999995001212, I need the result to be 0.659.

+1  A: 

If you want 0.659999 to be 'rounded' to 0.659, you're truncating, not rounding...

Also, you probably want to use the standard ROUND function, which can be used for truncating as well. See the answers to this question

jeroenh
The result of the calculation as provided by the OP is 0.65000...not 0.659999...round would make no difference in this case as it's down to the datatype being used.
AdaTheDev
@AdaTheDev: my main point is that this calculation is a truncation, not a rounding operation. Also, the T-SQL round function can be used for truncating as well. Updated my answer accordingly.
jeroenh
@jeroenh - yep, I agree with the truncating point. It's just that in this case, ROUND/truncating alone isn't the answer. Without the main point re: the datatypes involved in the calculation, ROUND/truncating will make no difference.
AdaTheDev
A: 

To get the same result as a calculator, you need to use FLOAT, not MONEY:

DECLARE @Val1 float 
DECLARE @Val2 float
SET @Val1= 554.5344
SET @Val2= 84020.3700
DECLARE @Result float
SET @Result = @Val1/@Val2 *100
SELECT @Result

gives: 0.65999995001212

AdaTheDev
+2  A: 

Result can't be 0.659 - exact result rounded to 5 places is 0.66000.

And you should never divide money by money :) At least not directly; correct result can be obtained as follows:

DECLARE @Val1 money = 554.5344
DECLARE @Val2 money = 84020.37
DECLARE @Result decimal(6,5) = cast(@Val1 as float)/@Val2*100
SELECT @Result
Arvo
True, dividing money by money can cause problems, but float can lead to incorrect rounding as well. Check out this example:SELECT 5555/CAST(1000 AS float),CAST(5555/CAST(1000 AS float) AS numeric(5, 2)),5555/CAST(1000 AS decimal),CAST(5555/CAST(1000 AS decimal) AS Numeric(5, 2))
Actually for all cases it needs to analyze, what kind of precision we need and where it can be lost. When we should round intermediates (most of financial source data processing), then often fixed types are better; when we do some kind of mathematical analyzis, then floating point is usually more suitable.
Arvo
A: 

Try this:

DECLARE @Val1 money = 554.5344 
DECLARE @Val2 money = 84020.37 
DECLARE @Result decimal(6,3) = @Val1 * 100 / @Val2
SELECT @Result

Your problem is that MONEY has only 4 decimal places, so when you divide 554.5344 by 84020.37 you get 0.0065, so when you multiply it by 100 you get 0.6500. If you multiply by 100 first, you are dividing 55453.44 by 84020.37 and getting 0.659, which is what you want.

Gabe
A: 

To get the all the values after decimal you should to use float. Then use round[1] function.

DECLARE @Val1 float
DECLARE @Val2 float SET @Val1= 554.5344 SET @Val2= 84020.3700 DECLARE @Result float SET @Result = round(@Val1/@Val2 *100, 3) SELECT @Result

Visit my Blog: http://expertdevelopersblog.blogspot.com/

Manas Sahu