[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c

Rounding in tnteger division

pozz

5/27/2011 7:57:00 PM

I'm sure, but I think C language doesn't specify a precise method of
rounding for integer division. Indeed, GNU C library says
(www.gnu.org/s/hello/manual/libc/Integer-Division.html)

These functions are redundant when GNU CC is used, because in GNU C
the â??/â?? operator always rounds towards zero. But in other C
implementations, â??/â?? may round differently with negative arguments.

I'd like to have a "round to nearest integer value"
(http://en.wikipedia.org/wiki/Rounding#Rounding_...), just using
integer arithmetics.

Actually I use this function:

#define ABS(x) ((x) > 0 ? (x) : -(x))
int
divround(int x, int y)
{
div_t d = div(x, y);
if (ABS(d.rem) > ABS(y) / 2) {
return d.quot + (d.quot > 0 ? +1 : -1);
} else {
return d.quot;
}
}

It should work well for positive and negative values. What do you think?
Is there a better approach?
3 Answers

Ben Pfaff

5/27/2011 8:14:00 PM

0

pozz <pozzugno@gmail.com> writes:

> I'm sure, but I think C language doesn't specify a precise method of
> rounding for integer division. Indeed, GNU C library says
> (www.gnu.org/s/hello/manual/libc/Integer-Division.html)
>
> These functions are redundant when GNU CC is used, because in GNU C
> the â??/â?? operator always rounds towards zero. But in other C
> implementations, â??/â?? may round differently with negative arguments.

This advice is true for C90, but C99 specifies rounding toward
zero:

The result of the / operator is the quotient from the
division of the first operand by the second; the result of
the % operator is the remainder. In both operations, if the
value of the second operand is zero, the behavior is
undefined.

When integers are divided, the result of the / operator is
the algebraic quotient with any fractional part
discarded.87) If the quotient a/b is representable, the
expression (a/b)*b + a%b shall equal a.

87) This is often called ``truncation toward zero''.

--
Ben Pfaff
http://be...

FX

6/2/2011 8:38:00 AM

0

pozz wrote :
> I'd like to have a "round to nearest integer value"
> (http://en.wikipedia.org/wiki/Rounding#Rounding_...), just using
> integer arithmetics.
>
> Actually I use this function:
>
> #define ABS(x) ((x) > 0 ? (x) : -(x))
> int
> divround(int x, int y)
> {
> div_t d = div(x, y);
> if (ABS(d.rem) > ABS(y) / 2) {
> return d.quot + (d.quot > 0 ? +1 : -1);
> } else {
> return d.quot;
> }
> }

I think this function returns -1 for 2/3, instead of +1, because d.quot
is 0, so d.quot > 0 fails. You should rather test the sign of d.rem.

pozz

6/3/2011 5:27:00 AM

0

Il 02/06/2011 10:38, FX ha scritto:
> pozz wrote :
>> I'd like to have a "round to nearest integer value"
>> (http://en.wikipedia.org/wiki/Rounding#Rounding_...), just
>> using integer arithmetics.
>>
>> Actually I use this function:
>>
>> #define ABS(x) ((x) > 0 ? (x) : -(x))
>> int
>> divround(int x, int y)
>> {
>> div_t d = div(x, y);
>> if (ABS(d.rem) > ABS(y) / 2) {
>> return d.quot + (d.quot > 0 ? +1 : -1);
>> } else {
>> return d.quot;
>> }
>> }
>
> I think this function returns -1 for 2/3, instead of +1, because d.quot
> is 0, so d.quot > 0 fails. You should rather test the sign of d.rem.

Yes, you're right. I think the corrected function is:
#define ABS(x) ((x) > 0 ? (x) : -(x))
int
divround(int x, int y)
{
div_t d = div(x, y);
if (ABS(d.rem) > ABS(y) / 2) {
return d.quot + (d.rem > 0 ? +1 : -1);
} else {
return d.quot;
}
}