This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c/16850] New: modulo - feature or bug?


This report deals with the behaviour of the modulo operator. 
According to the mathematical definition, i expect positive modulos 
(right operand) to give positive results (appendix A).  Whereas 
negative modulos should always yield negative results.  Adversely, 
programs compiled with gcc/g++ yield positive or negative results, 
depending on the sign of the moduland (left operand). 
 
To demonstrate the problem by examples i've written test programs 
in C and C++. When compiled by gcc and g++, these always produce 
the following output: 
---------------------------------------------- 
 
test of modulo operation 
 
operand set A (4 % 3 = 1): 1 ...OK 
operand set B (-4 % 3 = 2): -1 ...error 
  wrapping function: 2 ...OK 
operand set C (4 % -3 = -2): 1 ...error 
  wrapping function: -2 ...OK 
 
---------------------------------------------- 
I've attached the source codes (appendix B). 
 
I've observed that modulo behaviour 
of gcc/g++ on two machine types, pentium II (i386, i586), and Sun 
UltraSparc (sun4), using gcc/g++ compiler versions 3.3.1 (pentium) 
and 3.3.2 (Sun). 
Compilers/interpreters for other programming languages feature 
modulo operators that work like outlined in the beginning: 
- Perl, tested on version 5.8 (script attched) 
- Python, according to documentation (cf. modulo-doc.txt) 
 
A fix of these problems of gcc/g++ could affect many existing 
programs. Therefore, i'd understand if you hesitate to change 
the compilers' behaviour instantly.  But i would very much 
appreciate a command line option that makes the modulo operator 
available in its common mathematical definition. 
 
sincerly, 
Karol Szafranski 
 
 
appendix A 
---------- 
lists of some web documents that are concerned with the definition 
of the modulo operator. 
 
 
http://www.math.grin.edu/~stone/courses/fundamentals/integers.html 
 
  modulo 
  Inputs: moduland and modulus, both integers. 
  Output: result, an integer. 
  Precondition: modulus is not 0. 
  Postconditions: The difference between moduland and result is an exact 
    multiple of modulus. The magnitude of result is less than the 
    magnitude of modulus. If result is not 0, its sign is the same as the 
    sign of modulus. 
 
 
http://jacquardsystems.com/MComputing/1998/2/p18.htm 
[ see: beginning at zero ] 
 
  ... set {0, 1, 2, 3, 4} in a cyclical fashion ... 
 
 
http://www.templetons.com/brad/alice/language/language4.html 
 
  The mod Operator 
  ================ 
  The mod operator stands for the mathematical ``modulo'' operation. Its 
operands 
  must both be integer. The general form of the operation is  
       A mod B 
  where A and B are expressions. The value of B must be positive.  
  The result of the mod operation is always non-negative, and is equal to A 
  modulo B. If A is non-negative, ... 
 
 
http://coding.jpl.nasa.gov/~hamkins/source_code/C/
communications,signal_processing/comm.c 
[Jon Hamkins suggest wrapping of the modulo operand. However, there's 
 no statement on mathematical versus C language definitions] 
 
  double 
  modulo(double x, double m) 
  { 
     if ((x=fmod(x,m))<0) x+=m;  /* avoid negative result */ 
     return(x); 
  } 
 
 
http://mail.python.org/pipermail/python-list/2002-November/131924.html 
 
  ... 
  >From th docs 
  """ 
  The modulo operator always yields a result with the same sign as 
  its second operand (or zero); the absolute value of the result 
  is strictly smaller than the second operand. 
  """ 
 
 
appendix B 
---------- 
 
/
******************************************************************************* 
 
  Demo of Modulo Operation - modulo-demo.c 
 
*******************************************************************************/ 
#include <stdio.h> 
#include <string.h> 
 
 
long 
modulo_correct (long moduland, long modulus) { 
  moduland %= modulus; 
  if (modulus>0 && moduland<0) moduland += modulus; 
  if (modulus<0 && moduland>0) moduland += modulus; 
  return moduland;  
} 
 
 
int 
main (void) { 
  enum  modulo_args { sfx_moduland, sfx_modulus, sfx_result }; 
  long  TestSet[][3] = { 
    {  4,  3,  1 }, 
    { -4,  3,  2 }, 
    {  4, -3, -2 }, 
    {0,0,0} }; 
   
  printf ("\n"); 
  printf ("test of modulo operation\n"); 
  printf ("\n"); 
 
  // test string interface 
  int ctset=0; 
  for (ctset=0; TestSet[ctset][sfx_modulus]; ++ctset) { 
    long ret = TestSet[ctset][sfx_moduland] % TestSet[ctset][sfx_modulus]; 
    printf ("operand set %c (%ld %% %ld = %ld): %ld ...%s\n", ctset+65, 
      TestSet[ctset][sfx_moduland], TestSet[ctset][sfx_modulus], 
      TestSet[ctset][sfx_result], 
      ret, (ret==TestSet[ctset][sfx_result])?"OK":"error"); 
    if (ret!=TestSet[ctset][sfx_result]) { 
      ret = modulo_correct (TestSet[ctset][sfx_moduland], TestSet[ctset]
[sfx_modulus]); 
      printf ("  wrapping function: %ld ...%s\n", 
	ret, (ret==TestSet[ctset][sfx_result])?"OK":"error"); 
    } 
  } 
 
  printf ("\n"); 
  return 0; 
}

-- 
           Summary: modulo - feature or bug?
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: szak at gmx dot de
                CC: gcc-bugs at gcc dot gnu dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=16850


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]