Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Round to n Significant Figures in SQL

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.

like image 843
Paul Avatar asked Dec 17 '09 10:12

Paul


People also ask

How do you round to significant figures in SQL?

select round(@number,@sf-1- floor(log10(abs(@number)))) should do the trick !

How do you round off to significant figures?

To round to a significant figure: look at the first non-zero digit if rounding to one significant figure. look at the digit after the first non-zero digit if rounding to two significant figures. draw a vertical line after the place value digit that is required.

What means '%' in SQL?

The SQL LIKE Operator The percent sign (%) represents zero, one, or multiple characters. The underscore sign (_) represents one, single character.

How do you round off without a decimal in SQL?

SELECT CEILING(@value); SELECT FLOOR(@value); In the output, we can see that all three SQL Rounding functions (Round, CEILING and Floor) return the same output for the positive integer value. We do not have any decimal digit; therefore, Round function does not round the value.


3 Answers

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
like image 119
Brann Avatar answered Oct 19 '22 10:10

Brann


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)

like image 38
R Harris Avatar answered Oct 19 '22 10:10

R Harris


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
like image 22
Paul Avatar answered Oct 19 '22 10:10

Paul