Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8567273
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 11, 20262026-06-11T17:50:40+00:00 2026-06-11T17:50:40+00:00

the round(numeric,integer) function in PostgreSQL only rounds up: round(cast (41.0255 as numeric),3) ==> 41.026

  • 0

the round(numeric,integer) function in PostgreSQL only rounds up:

round(cast (41.0255 as numeric),3) ==> 41.026

Since we need a round function which returns 41.025 and (quite surprisingly) there isn’t such a function in PostgreSQL (we’re using 9.1.5), we wrote a “wrapper” function which in the very first version is quite naive and rough…but we didn’t find anything better due the lack of native support for this kind of problems in plpgsql.

The code is showed below. The problem is that it’s too slow for our purposes.
Could you suggest a better way to deal with this task?

Here’s the code:

    CREATE OR REPLACE FUNCTION round_half_down(numeric,integer) RETURNS numeric 
    AS $$
    DECLARE
      arg ALIAS FOR $1;
      rnd ALIAS FOR $2;
      tmp1 numeric;
      res numeric;
    BEGIN
      tmp1:=arg;
      IF cast(tmp1 as varchar) ~ '5$'  THEN res:=trunc(arg,rnd);
      ELSE res:=round(arg,rnd);
      END IF;

      RETURN res;
    END;
    $$ LANGUAGE plpgsql;

I need to cast the numeric value and use regexp…that’s what (I suppose) kills performances.

Just so you know: we need this because we have to compare numbers that were stored in two different columns (on two different tables) but with different numeric data type: one is double and one is real. The problem is that when inserting into a real data type column, PostgreSQL performs ROUND HALF DOWN while it doesn’t provide such option via its mathematical functions!

EDIT:
The function is actually bugged. Was a first quick rewriting as an attempt to improve performances of a working function but very slow.

Behavior must match the following:
IF the decimal digit being put off from rounding is <=5 => trunc
ELSE round up.

Some examples:

select round_half_down(cast (41.002555 as numeric),3) -- 41.002 
select round_half_down(cast (41.002555 as numeric),4) -- 41.0025 
select round_half_down(cast (41.002555 as numeric),5) -- 41.00255 

while the round function in PostgreSQL gives:

select round(cast (41.002555 as numeric),3) -- 41.003
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-11T17:50:41+00:00Added an answer on June 11, 2026 at 5:50 pm

    We have to compare numbers that were stored in two different columns
    (on two different tables) but with different numeric data type: one is
    double and one is real.

    This should be extremely fast and simple:

    SELECT dp_col, real_col
    FROM   tbl
    WHERE  dp_col::real = real_col
    

    Basically, just cast the double precision number to real for comparison.


    If that doesn’t work for you, this SQL function should do a proper job and work faster:

    CREATE OR REPLACE FUNCTION round_half_down1(numeric, int)
      RETURNS numeric LANGUAGE sql AS
    $func$
    SELECT CASE WHEN abs($1%0.1^$2) < .6 * 0.1^$2 THEN
             trunc($1, $2)
        ELSE round($1, $2) END;
    $func$
    

    Now fixed for negative numbers, with input from @sufleR in the comments.
    You can also just use the contained CASE expression.

    % .. modulo operator
    ^ .. exponentiation


    Here is a quick test you can use for benchmarking:

    SELECT n                                   -- Total runtime: 36.524 ms
          ,round_half_down1(n,3)               -- Total runtime: 70.493 ms
          ,round_down_to_decimal_places(n,3)   -- Total runtime: 74.690 ms
          ,round_half_down(n,3)                -- Total runtime: 82.191 ms
    FROM  (SELECT random()::numeric AS n FROM generate_series(1,10000)) x
    WHERE  round_down_to_decimal_places(n,3)
        <> round_half_down1(n,3)
    

    It also demonstrates how @Parveen’s function and your edited version miscalculate – they trunc() where they shouldn’t.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm looking for a numeric type in ILE RPG which will wrap round when
I need to round floating point numbers up to the nearest integer, even if
I need to round of numeric in my view. But there twig is used.
I need to format a numeric value in a UITextField which will format as
I've a form in which I want the calculate function to be called and
I need to convert pounds to kilograms and vice versa -- and round the
The documentation for the round() function states that you pass it a number, and
How can I round a decimal number (floating point) to the nearest integer? e.g.
I am trying to convert numeric format to an integer in R. This is
I need to compare numeric data from two datatables with the same schema. For

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.