Round to n Significant Figures in SQL

前端 未结 4 1533
-上瘾入骨i
-上瘾入骨i 2021-02-18 14:38

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


        
相关标签:
4条回答
  • 2021-02-18 14:41

    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)

    0 讨论(0)
  • 2021-02-18 14:42

    You could divide by 100 before rounding and then multiplying by 100...

    0 讨论(0)
  • 2021-02-18 14:45

    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
    
    0 讨论(0)
  • 2021-02-18 15:03

    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
    
    0 讨论(0)
提交回复
热议问题