lrint and rounding mode

S

Spoon

Hello everyone,

I don't understand how the lrint() function works.

long lrint(double x);

The function returns the nearest long integer to x, consistent with the
current rounding mode. It raises an invalid floating-point exception if
the magnitude of the rounded value is too large to represent. And it
raises an inexact floating-point exception if the return value does not
equal x.

The output of the following program does not make sense to me.

#include <cstdio>
#include <cmath>
int main()
{
for (int i=-10; i < 10; ++i)
{
double x = i + 0.5;
printf("lrint(%+f)=%ld\n", x, lrint(x));
}
return 0;
}

$ g++ -std=c++98 -Wall -Wextra -O2 -march=pentium3 foo.cxx -lm
$ ./a.out
lrint(-9.500000)=-10
lrint(-8.500000)=-8
lrint(-7.500000)=-8
lrint(-6.500000)=-6
lrint(-5.500000)=-6
lrint(-4.500000)=-4
lrint(-3.500000)=-4
lrint(-2.500000)=-2
lrint(-1.500000)=-2
lrint(-0.500000)=0
lrint(+0.500000)=0
lrint(+1.500000)=2
lrint(+2.500000)=2
lrint(+3.500000)=4
lrint(+4.500000)=4
lrint(+5.500000)=6
lrint(+6.500000)=6
lrint(+7.500000)=8
lrint(+8.500000)=8
lrint(+9.500000)=10

How could 1.5 AND 2.5 be rounded to 2 in the same rounding mode?

Regards.
 
Z

Zara

Hello everyone,

I don't understand how the lrint() function works.

long lrint(double x);

The function returns the nearest long integer to x, consistent with the
current rounding mode. It raises an invalid floating-point exception if
the magnitude of the rounded value is too large to represent. And it
raises an inexact floating-point exception if the return value does not
equal x.

The output of the following program does not make sense to me.

lrint(+1.500000)=2
lrint(+2.500000)=2

How could 1.5 AND 2.5 be rounded to 2 in the same rounding mode?

I have seen it called the "banker rounding" (in spanish, but I suppose
it should be the same in english.

If the fractional part of the number is less than 0.5, it is rounded
down. If it is more than 0.5, it is rounded up. It it is exactly 0.5,
then if the integral part is odd, it is rounded up, else it is rounded
down.

It makes the rounding smoother, and the probability of accounting and
audit results being the same, higher.

best regards,

Zara
 
S

Spoon

Zara said:
I have seen it called the "banker rounding" (in spanish, but I suppose
it should be the same in english.

If the fractional part of the number is less than 0.5, it is rounded
down. If it is more than 0.5, it is rounded up. If it is exactly 0.5,
then if the integral part is odd, it is rounded up, else it is rounded
down.

It makes the rounding smoother, and the probability of accounting and
audit results being the same, higher.

I had not read the description of "round to nearest" carefully.

"Round toward the nearest integer with the closer value, or toward the
nearest even integer if two integers are equally near."

Therefore, by definition, "round to nearest" in C and C++ is different
from the mathematicians' "round to nearest".

In math, 2.5 is rounded to 3. In C++, 2.5 is rounded to 2.

Thanks for making me aware of this fact.
 
J

James Kanze

I don't understand how the lrint() function works.
long lrint(double x);

Just a technicality, but this function doesn't exist (yet) in
C++; it's part of C99. (On the other hand, it will be part of
the next C++ standard, and I would expect most implementations
of C++ to support it already.)
The function returns the nearest long integer to x, consistent with the
current rounding mode. It raises an invalid floating-point exception if
the magnitude of the rounded value is too large to represent. And it
raises an inexact floating-point exception if the return value does not
equal x.
The output of the following program does not make sense to me.
#include <cstdio>
#include <cmath>
int main()
{
for (int i=-10; i < 10; ++i)
{
double x = i + 0.5;
printf("lrint(%+f)=%ld\n", x, lrint(x));
}
return 0;

}
$ g++ -std=c++98 -Wall -Wextra -O2 -march=pentium3 foo.cxx -lm
$ ./a.out
lrint(-9.500000)=-10
lrint(-8.500000)=-8
lrint(-7.500000)=-8
lrint(-6.500000)=-6
lrint(-5.500000)=-6
lrint(-4.500000)=-4
lrint(-3.500000)=-4
lrint(-2.500000)=-2
lrint(-1.500000)=-2
lrint(-0.500000)=0
lrint(+0.500000)=0
lrint(+1.500000)=2
lrint(+2.500000)=2
lrint(+3.500000)=4
lrint(+4.500000)=4
lrint(+5.500000)=6
lrint(+6.500000)=6
lrint(+7.500000)=8
lrint(+8.500000)=8
lrint(+9.500000)=10
How could 1.5 AND 2.5 be rounded to 2 in the same rounding mode?

Those are the rules for IEEE round to nearest mode. In the case
of .5, it rounds to even. The reason for this is so that there
will be no overall bias in the rounding; if you use the
"standard" rounding, with 0.5 rounding up, you introduce a bias
towards higher values. (If you add the rounded positive values
in your example, the results will be very close to the results
of adding the unrounded values if IEEE round to nearest is used;
with the classical commercial rounding, they would be
significantly greater.)

Note that you cannot always use this rounding in commercial
software; most countries have laws concerning what is good
bookkeeping practices, and impose very specific rules of
rounding, including the fact that 0.5 cents always rounds away
from 0. (Of course, since the rules are based on decimal
values, you generally can't use double directly anyway.)
 
J

James Kanze

[...]
I have seen it called the "banker rounding" (in spanish, but I suppose
it should be the same in english.

I think you've got it backwards. In banking, .5 always rounds
away from zero. It's the specialists in numeric analysis (the
mathematiciens) who insist on round to even; it means that the
average error will be 0, instead of being slightly greater than
zero.
If the fractional part of the number is less than 0.5, it is
rounded down. If it is more than 0.5, it is rounded up. It it
is exactly 0.5, then if the integral part is odd, it is
rounded up, else it is rounded down.
It makes the rounding smoother, and the probability of
accounting and audit results being the same, higher.

Accounting and audit results will be the same if both use the
same rounding rules (including where the rounding occurs). In
most countries, these rules are imposed by law, and require that
0.005 be rounded to 0.01. (In the EU, the law actually requires
that all calculations be done with 5 decimal digits precision,
and that the final result be rounded to 2 decimal digits.) Note
too that because these rules are normally expressed in terms of
decimal arithmetic and rounding of decimal digits, you can't use
machine floating point directly.
 
P

Pete Becker

[...]
lrint(+1.500000)=2
lrint(+2.500000)=2
How could 1.5 AND 2.5 be rounded to 2 in the same rounding mode?
I have seen it called the "banker rounding" (in spanish, but I suppose
it should be the same in english.

I think you've got it backwards. In banking, .5 always rounds
away from zero. It's the specialists in numeric analysis (the
mathematiciens) who insist on round to even; it means that the
average error will be 0, instead of being slightly greater than
zero.

Nevertheless, I've also heard "round to even" called "banker's
rounding." And that most reliable of sources, Wikipedia, agrees:
http://en.wikipedia.org/wiki/Rounding#Round-to-even_method.
 
A

Alf P. Steinbach

* Pete Becker:
[...]
lrint(+1.500000)=2
lrint(+2.500000)=2

How could 1.5 AND 2.5 be rounded to 2 in the same rounding mode?
I have seen it called the "banker rounding" (in spanish, but I suppose
it should be the same in english.

I think you've got it backwards. In banking, .5 always rounds
away from zero. It's the specialists in numeric analysis (the
mathematiciens) who insist on round to even; it means that the
average error will be 0, instead of being slightly greater than
zero.

Nevertheless, I've also heard "round to even" called "banker's
rounding." And that most reliable of sources, Wikipedia, agrees:
http://en.wikipedia.org/wiki/Rounding#Round-to-even_method.

Yes. Banker's rounding is round to even. And James is partially right
because that article explains

"The origin of the term bankers' rounding is more obscure. If this
rounding method was ever a standard in banking, the evidence has proved
extremely difficult to find. To the contrary, section 2 of the European
Commission report The Introduction of the Euro and the Rounding of
Currency Amounts [2] suggests that there had previously been no standard
approach to rounding in banking."

The referenced European Commission document prescribes rounding "up" for
conversion to Euro, but seems to fail to define "up".

Cheers,

- Alf
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,073
Latest member
DarinCeden

Latest Threads

Top