Round to n Significant Figures in SQL

21,372

Solution 1

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

Solution 2

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))))

  • The part that does the work - uses ROUND function on the number as normal, but the length to be rounded to is calculated
  • ABS ensures positive
  • LOG10 gets the number of digits greater than 0 in the number
  • FLOOR gets the largest integer smaller than the resultant number
  • So always rounds down and gives an integer
  • sf - 1 - FLOOR(...) gives a negative number
  • 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)

Solution 3

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
Share:
21,372
Momo
Author by

Momo

I work as a software development manager, working mostly with C#, Azure and SQL Server.

Updated on July 17, 2022

Comments

  • Momo
    Momo almost 2 years

    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
    

    I am aware of the ROUND() function, which rounds to n decimal places rather than significant figures.