Subject | RE: [firebird-support] Re: Is this a bug in ROUND function? |
---|---|

Author | Alan McDonald |

Post date | 2019-08-29T22:14:49Z |

On 8/29/19 4:45 AM, m.djorov@... [firebird-support] wrote:

The value that you get at that point will be the nearest value to 2.725 that is expressible as a double precision floating point number which will be slightly different since 2.725 is NOT exactly representable as double precision floating point number. The number you get is allowed to be either the representable value just below or just above, the value, though the preference is the closer one. If the number you get is something like 2.72499...xx then round needs to round down, if you get something like 2.72500..xx then round needs to round up.

If the numbers you had WERE exactly representable, like 2.625 (21/8) then the rules on how to round would matter, but since the number you have, after being made representable, isn't exactly 0.5 in the fractional part, that clause doesn't apply.

--

Richard Damon

What about:

select

round(cast(0.725 as double precision), 2),

round(cast(1.725 as double precision), 2),

round(cast(2.725 as double precision), 2),

round(cast(3.725 as double precision), 2),

round(cast(4.725 as numeric(18,3)), 2),

round(cast(5.725 as double precision), 2),

round(cast(6.725 as double precision), 2),

round(cast(7.725 as double precision), 2),

round(cast(8.725 as double precision), 2),

round(cast(9.725 as double precision), 2),

round(cast(10.725 as double precision), 2) from

rdb$database

>The issue is that when you write: cast(2.725 as double precision) you aren't dealing with 'mathematics' anymore, or even the value 2.725

> In binary representation of the values maybe 4.72 is the closest, but

> we are talking about mathematic.

> This is from the description of the ROUND function in the documentation:

> Rounds a number to the nearest integer. If the fractional part is

> exactly 0.5, rounding is upward for positive numbers and downward for

> negative numbers.

> So .725 is all cases is rounded up to .73 as it should be, but in one

> case it is not.

>

The value that you get at that point will be the nearest value to 2.725 that is expressible as a double precision floating point number which will be slightly different since 2.725 is NOT exactly representable as double precision floating point number. The number you get is allowed to be either the representable value just below or just above, the value, though the preference is the closer one. If the number you get is something like 2.72499...xx then round needs to round down, if you get something like 2.72500..xx then round needs to round up.

If the numbers you had WERE exactly representable, like 2.625 (21/8) then the rules on how to round would matter, but since the number you have, after being made representable, isn't exactly 0.5 in the fractional part, that clause doesn't apply.

--

Richard Damon

What about:

select

round(cast(0.725 as double precision), 2),

round(cast(1.725 as double precision), 2),

round(cast(2.725 as double precision), 2),

round(cast(3.725 as double precision), 2),

round(cast(4.725 as numeric(18,3)), 2),

round(cast(5.725 as double precision), 2),

round(cast(6.725 as double precision), 2),

round(cast(7.725 as double precision), 2),

round(cast(8.725 as double precision), 2),

round(cast(9.725 as double precision), 2),

round(cast(10.725 as double precision), 2) from

rdb$database