I would like to be able to round a number to n significant figures in SQL. So:
123.456 rounded to 2sf would give 120
0.00123 rounded to 2sf would give 0.0012
Adapted the most popular answer by Brann to MySQL for those who come looking like me.
CREATE FUNCTION `sfround`(num FLOAT, sf INT) # creates the function
RETURNS float # defines output type
DETERMINISTIC # given input, will return same output
BEGIN
DECLARE r FLOAT; # make a variable called r, defined as a float
IF( num IS NULL OR num = 0) THEN # ensure the number exists, and isn't 0
SET r = num; # if it is; leave alone
ELSE
SET r = ROUND(num, sf - 1 - FLOOR(LOG10(ABS(num))));
/* see below*/
END IF;
RETURN (r);
END
/* Felt too long to put in comment */
ROUND(num, sf - 1 - FLOOR(LOG10(ABS(num))))
works because ROUND(num, -ve num) rounds to the left of the decimal point
For just a one off, ROUND(123.456, -1) and ROUND(0.00123,4) return the requested answers ((120, 0.0012)
You could divide by 100 before rounding and then multiplying by 100...
I think I've managed it.
CREATE FUNCTION RoundSigFig(@Number float, @Figures int)
RETURNS float
AS
BEGIN
DECLARE @Answer float;
SET @Answer = (
SELECT
CASE WHEN intPower IS NULL THEN 0
ELSE FLOOR(fltNumber * POWER(CAST(10 AS float), intPower) + 0.5)
* POWER(CAST(10 AS float), -intPower)
END AS ans
FROM (
SELECT
@Number AS fltNumber,
CASE WHEN @Number > 0
THEN -((CEILING(LOG10(@Number)) - @Figures))
WHEN @Number < 0
THEN -((FLOOR(LOG10(@Number)) - @Figures))
ELSE NULL END AS intPower
) t
);
RETURN @Answer;
END
select round(@number,@sf-1- floor(log10(abs(@number))))
should do the trick !
Successfully tested on your two examples.
Edit : Calling this function on @number=0 won't work. You should add a test for this before using this code.
create function sfround(@number float, @sf int) returns float as
begin
declare @r float
select @r = case when @number = 0 then 0 else round(@number ,@sf -1-floor(log10(abs(@number )))) end
return (@r)
end