public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Remainder ( % ) operator and GCC
@ 2005-11-09 13:19 Ladislav Mecir
  2005-11-09 13:53 ` John Love-Jensen
  2005-11-09 19:19 ` Ian Lance Taylor
  0 siblings, 2 replies; 8+ messages in thread
From: Ladislav Mecir @ 2005-11-09 13:19 UTC (permalink / raw)
  To: GCC Help

Hi all, new to this list.

Could you give me an advice how to make the following program (and 
programs using many times the % operator) run reliably when compiled by 
GCC on different operating systems even when the user gives -1 as the B 
value?

#include <stdio.h>
int main(int argc, char *argv[]) {
    int a = -2147483647;
    int b;
    printf ("The value of B: ");
    scanf ("%i", &b);
    printf ("%i %% %i: %i", a, b, (a - 1) % b);
    return 0;
}

TIA

L.M.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Remainder ( % ) operator and GCC
  2005-11-09 13:19 Remainder ( % ) operator and GCC Ladislav Mecir
@ 2005-11-09 13:53 ` John Love-Jensen
  2005-11-09 19:19 ` Ian Lance Taylor
  1 sibling, 0 replies; 8+ messages in thread
From: John Love-Jensen @ 2005-11-09 13:53 UTC (permalink / raw)
  To: Ladislav Mecir, MSX to GCC

Hi Ladislav,

Results are platform dependent.

Don't use negative numbers for the MOD operator.

HTH,
--Eljay

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Remainder ( % ) operator and GCC
  2005-11-09 13:19 Remainder ( % ) operator and GCC Ladislav Mecir
  2005-11-09 13:53 ` John Love-Jensen
@ 2005-11-09 19:19 ` Ian Lance Taylor
  2005-11-09 19:34   ` Frans Englich
  1 sibling, 1 reply; 8+ messages in thread
From: Ian Lance Taylor @ 2005-11-09 19:19 UTC (permalink / raw)
  To: Ladislav Mecir; +Cc: GCC Help

Ladislav Mecir <lmecir@mbox.vol.cz> writes:

> Could you give me an advice how to make the following program (and
> programs using many times the % operator) run reliably when compiled
> by GCC on different operating systems even when the user gives -1 as
> the B value?
> 
> #include <stdio.h>
> int main(int argc, char *argv[]) {
>     int a = -2147483647;
>     int b;
>     printf ("The value of B: ");
>     scanf ("%i", &b);
>     printf ("%i %% %i: %i", a, b, (a - 1) % b);
>     return 0;
> }

Don't use '%'.  It is machine dependent when used with a negative
number.

This is not a gcc question.

Ian

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Remainder ( % ) operator and GCC
  2005-11-09 19:19 ` Ian Lance Taylor
@ 2005-11-09 19:34   ` Frans Englich
  2005-11-09 19:38     ` corey taylor
  2005-11-09 20:05     ` Ian Lance Taylor
  0 siblings, 2 replies; 8+ messages in thread
From: Frans Englich @ 2005-11-09 19:34 UTC (permalink / raw)
  To: gcc-help, lmecir

On Wednesday 09 November 2005 19:19, Ian Lance Taylor wrote:
> Ladislav Mecir <lmecir@mbox.vol.cz> writes:
> > Could you give me an advice how to make the following program (and
> > programs using many times the % operator) run reliably when compiled
> > by GCC on different operating systems even when the user gives -1 as
> > the B value?
> >
> > #include <stdio.h>
> > int main(int argc, char *argv[]) {
> >     int a = -2147483647;
> >     int b;
> >     printf ("The value of B: ");
> >     scanf ("%i", &b);
> >     printf ("%i %% %i: %i", a, b, (a - 1) % b);
> >     return 0;
> > }
>
> Don't use '%'.  It is machine dependent when used with a negative
> number.

What should one use instead? What is the portable, machine-independent 
alternative?


Cheers,

		Frans

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Remainder ( % ) operator and GCC
  2005-11-09 19:34   ` Frans Englich
@ 2005-11-09 19:38     ` corey taylor
  2005-11-09 19:52       ` Frans Englich
  2005-11-09 20:05     ` Ian Lance Taylor
  1 sibling, 1 reply; 8+ messages in thread
From: corey taylor @ 2005-11-09 19:38 UTC (permalink / raw)
  To: Frans Englich; +Cc: gcc-help, lmecir

You could use fmod.

corey

On 11/9/05, Frans Englich <frans.englich@telia.com> wrote:
> On Wednesday 09 November 2005 19:19, Ian Lance Taylor wrote:
> > Ladislav Mecir <lmecir@mbox.vol.cz> writes:
> > > Could you give me an advice how to make the following program (and
> > > programs using many times the % operator) run reliably when compiled
> > > by GCC on different operating systems even when the user gives -1 as
> > > the B value?
> > >
> > > #include <stdio.h>
> > > int main(int argc, char *argv[]) {
> > >     int a = -2147483647;
> > >     int b;
> > >     printf ("The value of B: ");
> > >     scanf ("%i", &b);
> > >     printf ("%i %% %i: %i", a, b, (a - 1) % b);
> > >     return 0;
> > > }
> >
> > Don't use '%'.  It is machine dependent when used with a negative
> > number.
>
> What should one use instead? What is the portable, machine-independent
> alternative?
>
>
> Cheers,
>
>                 Frans
>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Remainder ( % ) operator and GCC
  2005-11-09 19:38     ` corey taylor
@ 2005-11-09 19:52       ` Frans Englich
  0 siblings, 0 replies; 8+ messages in thread
From: Frans Englich @ 2005-11-09 19:52 UTC (permalink / raw)
  To: gcc-help

On Wednesday 09 November 2005 19:38, corey taylor wrote:
> You could use fmod.

But isn't fmod for floating point mod computation? From what I've understood 
"%" when invoked with integers beforms integer remainder compuation, as 
opposed to floating point.


Cheers,

		Frans


>
> corey
>
> On 11/9/05, Frans Englich <frans.englich@telia.com> wrote:
> > On Wednesday 09 November 2005 19:19, Ian Lance Taylor wrote:
> > > Ladislav Mecir <lmecir@mbox.vol.cz> writes:
> > > > Could you give me an advice how to make the following program (and
> > > > programs using many times the % operator) run reliably when compiled
> > > > by GCC on different operating systems even when the user gives -1 as
> > > > the B value?
> > > >
> > > > #include <stdio.h>
> > > > int main(int argc, char *argv[]) {
> > > >     int a = -2147483647;
> > > >     int b;
> > > >     printf ("The value of B: ");
> > > >     scanf ("%i", &b);
> > > >     printf ("%i %% %i: %i", a, b, (a - 1) % b);
> > > >     return 0;
> > > > }
> > >
> > > Don't use '%'.  It is machine dependent when used with a negative
> > > number.
> >
> > What should one use instead? What is the portable, machine-independent
> > alternative?
> >
> >
> > Cheers,
> >
> >                 Frans

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Remainder ( % ) operator and GCC
  2005-11-09 19:34   ` Frans Englich
  2005-11-09 19:38     ` corey taylor
@ 2005-11-09 20:05     ` Ian Lance Taylor
  1 sibling, 0 replies; 8+ messages in thread
From: Ian Lance Taylor @ 2005-11-09 20:05 UTC (permalink / raw)
  To: Frans Englich; +Cc: gcc-help, lmecir

Frans Englich <frans.englich@telia.com> writes:

> > Don't use '%'.  It is machine dependent when used with a negative
> > number.
> 
> What should one use instead? What is the portable, machine-independent 
> alternative?

The div function.

Ian

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Remainder ( % ) operator and GCC
@ 2005-11-09 21:47 Nelson H. F. Beebe
  0 siblings, 0 replies; 8+ messages in thread
From: Nelson H. F. Beebe @ 2005-11-09 21:47 UTC (permalink / raw)
  To: gcc-help; +Cc: beebe

Discussion today on this list about the use of the C remainder
operator, %, met with suggestions to use fmod() and div().

This is not a gcc-specific question, and thus is off-topic for this
list.  Nevertheless, it is a frequent source of misunderstanding
(i.e., coding bugs), so I answer it below in depth.

The meaning of the remainder operator for negative arguments was
defined to be IMPLEMENTATION DEPENDENT in 1989 ISO C (and was so in
historical K&R implementations), but that was fixed in the 1999
Standard.

The relevant text from the 1999 ISO C Standard appears at the end of
this message.  Please remember that it will still be several years
before C99-conforming compilers are widely the norm: don't rely on the
behavior of the % operator if you need to run on a wide range of
platforms with many different compilers.

In summary, div() will just get you the same result as %.

fmod() has floating-point arguments, and needs careful use to ensure
that bits are not lost in conversion from integer to floating-point.
For example, you cannot do (float)int_foo without risk of bit loss on
most current platforms, but you CAN safely do (double)int_foo on those
systems.

The C99 definition of % operator (see below) implies the following
behavior:

        17 % 3    ->  2
        17 % -3   ->  2
        -17 % 3   -> -2
        -17 % -3  -> -2

The results from fmod() are the same as those for %.

To get the right answer, take the remainder of division of positive
integers, and attach the sign of the first number.  If you implement
your own function to do this portably, however, you must also take
care to handle the case of the most negative integer: on two's
complement systems (virtually all computers on which C runs), that
number has no corresponding positive value.  Thus, -2147483648 % 3 =
-2 and -(-2147483648) % 3 = -2: notice the sign of the latter.

The remainder() function behaves differently:

        remainder(17, 3)   -> -1
        remainder(17, -3)  -> -1
        remainder(-17, 3)  ->  1
        remainder(-17, -3) ->  1

Here is the standardese:

>> ...
>>      6.5.5 Multiplicative operators
>>
>>      Syntax
>>
>> 1           multiplicative-expression:
>>                     cast-expression
>>                     multiplicative-expression * cast-expression
>>                     multiplicative-expression / cast-expression
>>                     multiplicative-expression % cast-expression
>>
>>      Constraints
>>
>> 2    Each of the operands shall have arithmetic type. The operands of the
>>      % operator shall have integer type.
>>
>>      Semantics
>>
>> 3    The usual arithmetic conversions are performed on the operands.
>>
>> 4    The result of the binary * operator is the product of the operands.
>>
>> 5    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.
>>
>> 6    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.
>> ...

>> ...
>>      7.8.2.2 The imaxdiv function
>>
>>      Synopsis
>>
>> 1                #include <inttypes.h>
>>                  imaxdiv_t imaxdiv(intmax_t numer, intmax_t denom);
>>
>>      Description
>>
>> 2    The imaxdiv function computes numer / denom and numer % denom in a
>>      single operation.
>>
>>      Returns
>>
>> 3    The imaxdiv function returns a structure of type imaxdiv_t
>>      comprising both the quotient and the remainder. The structure
>>      shall contain (in either order) the members quot (the quotient)
>>      and rem (the remainder), each of which has type intmax_t. If
>>      either part of the result cannot be represented, the behavior is
>>      undefined.
>> ...

>> ...
>>      7.20.6.2 The div, ldiv, and lldiv functions
>>
>>      Synopsis
>>
>> 1         #include <stdlib.h>
>>           div_t div(int numer, int denom);
>>           ldiv_t ldiv(long int numer, long int denom);
>>           lldiv_t lldiv(long long int numer, long long int denom);
>>
>>      Description
>>
>> 2    The div, ldiv, and lldiv, functions compute numer / denom and
>>      numer % denom in a single operation.
>>
>>      Returns
>>
>> 3    The div, ldiv, and lldiv functions return a structure of type
>>      div_t, ldiv_t, and lldiv_t, respectively, comprising both the
>>      quotient and the remainder. The structures shall contain (in
>>      either order) the members quot (the quotient) and rem (the
>>      remainder), each of which has the same type as the arguments
>>      numer and denom. If either part of the result cannot be
>>      represented, the behavior is undefined.
>> ...


>> ...
>>      7.12.10.1 The fmod functions
>>
>>      Synopsis
>>
>> 1        #include <math.h>
>>          double fmod(double x, double y);
>>          float fmodf(float x, float y);
>>          long double fmodl(long double x, long double y);
>>
>>      Description
>>
>> 2    The fmod functions compute the floating-point remainder of x/y.
>>
>>      Returns
>>
>> 3    The fmod functions return the value x - ny, for some integer n
>>      such that, if y is nonzero, the result has the same sign as x
>>      and magnitude less than the magnitude of y. If y is zero,
>>      whether a domain error occurs or the fmod functions return
>>      zero is implementation- defined.
>>
>> ...

>> ...
>>      7.12.10.2 The remainder functions
>>
>>      Synopsis
>>
>> 1        #include <math.h>
>>          double remainder(double x, double y);
>>          float remainderf(float x, float y);
>>          long double remainderl(long double x, long double y);
>>
>>      Description
>>
>> 2    The remainder functions compute the remainder x REM y required by
>>      IEC 60559. 201)
>>
>>      Returns
>>
>> 3    The remainder functions return x REM y.
>>
>>
>>      201) ``When y 0, the remainder r = x REM y is defined
>>      regardless of the rounding mode by the mathematical relation r
>>      = x - ny, where n is the integer nearest the exact value of
>>      x/y; whenever | n - x/y | = 1/2, then n is even.  Thus, the
>>      remainder is always exact.  If r = 0, its sign shall be that
>>      of x.'' This definition is applicable for all implementations.
>> ...

>> ...
>>      7.12.10.3 The remquo functions
>>
>>      Synopsis
>>
>> 1        #include <math.h>
>>          double remquo(double x, double y, int *quo);
>>          float remquof(float x, float y, int *quo);
>>          long double remquol(long double x, long double y,
>>                  int *quo);
>>
>>      Description
>>
>> 2    The remquo functions compute the same remainder as the remainder
>>      functions. In the object pointed to by quo they store a value
>>      whose sign is the sign of x/y and whose magnitude is congruent
>>      modulo 2n to the magnitude of the integral quotient of x/y, where
>>      n is an implementation-defined integer greater than or equal to 3.
>>
>>      Returns
>>
>> 3    The remquo functions return x REM y.
>> ...

-------------------------------------------------------------------------------
- Nelson H. F. Beebe                    Tel: +1 801 581 5254                  -
- University of Utah                    FAX: +1 801 581 4148                  -
- Department of Mathematics, 110 LCB    Internet e-mail: beebe@math.utah.edu  -
- 155 S 1400 E RM 233                       beebe@acm.org  beebe@computer.org -
- Salt Lake City, UT 84112-0090, USA    URL: http://www.math.utah.edu/~beebe  -
-------------------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2005-11-09 21:47 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-11-09 13:19 Remainder ( % ) operator and GCC Ladislav Mecir
2005-11-09 13:53 ` John Love-Jensen
2005-11-09 19:19 ` Ian Lance Taylor
2005-11-09 19:34   ` Frans Englich
2005-11-09 19:38     ` corey taylor
2005-11-09 19:52       ` Frans Englich
2005-11-09 20:05     ` Ian Lance Taylor
2005-11-09 21:47 Nelson H. F. Beebe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).