From: Michael Hope <michaelh@ju...>  20010513 17:27:55

This code (from support/regression/tests/muldiv.c): static void testMod(void) { int i; // Disabled the LOG functions due to a bug in sdcc involving // vaargs. i = 100; // LOG(("i%%17 == 15 = %u\n", (int)(i%9))); ASSERT(i%17 == 15); // LOG(("i%%7 == 2 = %u\n", (int)i%7)); ASSERT(i%7 == 2); i = 49; // LOG(("i%%3 == 1 = %u\n", (int)i%3)); ASSERT(i%3 == 1); // LOG(("i%%5 == 4 = %u\n", (int)i%5)); ASSERT(i%5 == 4); } Fails on all but the first assert. Note that as all of the values are known sdcc optimises all of the calculations away. The common theme seems to be that the ones that fail involve a negative number.  Michael 
From: Brian Hurt <bhurt@ta...>  20010513 17:46:30

IIRC, modulo's of a negative number can work one of two ways in the C standard. 49%3 can return either 1 (16*3 + 1) or 2 (17*3 + 2). Returning 2 is usefull because it always gaurentees 0 <= x%i < i. Returning 1 is usefull because that way x%i == x  (x/i)*i (i.e. (x/i)*i + (x%i) == x), and 49/3 returns 16 (because 49/3 == 16). Some hardware returns one, some the other and the C standard allows the compiler designer to use the one the hardware does for efficiency. Worse yet, consider the result of 49%3  should it be 1, 2, 1, or 2? Note that whatever you pick, there is no number such that 0 <= x < 3. I note for the record mathematicians only seem to apply the modulo operation to the set of positive integers, the wimps. Brian On Sun, 13 May 2001, Michael Hope wrote: > This code (from support/regression/tests/muldiv.c): > > static void > testMod(void) > { > int i; > > // Disabled the LOG functions due to a bug in sdcc involving > // vaargs. > i = 100; > // LOG(("i%%17 == 15 = %u\n", (int)(i%9))); > ASSERT(i%17 == 15); > // LOG(("i%%7 == 2 = %u\n", (int)i%7)); > ASSERT(i%7 == 2); > > i = 49; > // LOG(("i%%3 == 1 = %u\n", (int)i%3)); > ASSERT(i%3 == 1); > // LOG(("i%%5 == 4 = %u\n", (int)i%5)); > ASSERT(i%5 == 4); > } > > > Fails on all but the first assert. Note that as all of the values are > known sdcc optimises all of the calculations away. The common theme seems > to be that the ones that fail involve a negative number. > >  Michael > > > > _______________________________________________ > sdccdevel mailing list > sdccdevel@... > http://lists.sourceforge.net/lists/listinfo/sdccdevel > 
From: Michael Hope <michaelh@ju...>  20010513 23:20:39

Nasty. I guess I'll have to disable these tests then. Incidently gcc, Java, and the z80 port all use the 'sign of the remainer follows the dividend' rule. I was surprised that thestatic evaluation code in sdcc follows different rules as I assumed they would map directly down into the gcc routines. Apparently you can't trust the modulo operator in Java either. Even though it's defined that way, some JITs use the native version of mod and produce the wrong result.  Michael On Sun, 13 May 2001, Brian Hurt wrote: > IIRC, modulo's of a negative number can work one of two ways in the C > standard. 49%3 can return either 1 (16*3 + 1) or 2 (17*3 + 2). > Returning 2 is usefull because it always gaurentees 0 <= x%i < i. > Returning 1 is usefull because that way x%i == x  (x/i)*i (i.e. (x/i)*i > + (x%i) == x), and 49/3 returns 16 (because 49/3 == 16). Some hardware > returns one, some the other and the C standard allows the compiler > designer to use the one the hardware does for efficiency. Worse yet, > consider the result of 49%3  should it be 1, 2, 1, or 2? Note that > whatever you pick, there is no number such that 0 <= x < 3. > > I note for the record mathematicians only seem to apply the modulo > operation to the set of positive integers, the wimps. > > Brian > > > On Sun, 13 May 2001, Michael Hope wrote: > > > This code (from support/regression/tests/muldiv.c): > > > > static void > > testMod(void) > > { > > int i; > > > > // Disabled the LOG functions due to a bug in sdcc involving > > // vaargs. > > i = 100; > > // LOG(("i%%17 == 15 = %u\n", (int)(i%9))); > > ASSERT(i%17 == 15); > > // LOG(("i%%7 == 2 = %u\n", (int)i%7)); > > ASSERT(i%7 == 2); > > > > i = 49; > > // LOG(("i%%3 == 1 = %u\n", (int)i%3)); > > ASSERT(i%3 == 1); > > // LOG(("i%%5 == 4 = %u\n", (int)i%5)); > > ASSERT(i%5 == 4); > > } > > > > > > Fails on all but the first assert. Note that as all of the values are > > known sdcc optimises all of the calculations away. The common theme seems > > to be that the ones that fail involve a negative number. > > > >  Michael > > > > > > > > _______________________________________________ > > sdccdevel mailing list > > sdccdevel@... > > http://lists.sourceforge.net/lists/listinfo/sdccdevel > > > > > _______________________________________________ > sdccdevel mailing list > sdccdevel@... > http://lists.sourceforge.net/lists/listinfo/sdccdevel > 
From: Sandeep Dutta <sandeep@dd...>  20010514 04:20:38

Fixed this , it was in operandOperation , should not cast to unsigned unconditionally. Sandeep Original Message From: sdccdeveladmin@... [mailto:sdccdeveladmin@...]On Behalf Of Michael Hope Sent: Sunday, May 13, 2001 10:27 AM To: sdccdevel@... Subject: [sdccdevel] bug: mod (%) involving constants and negatives is broken. This code (from support/regression/tests/muldiv.c): static void testMod(void) { int i; // Disabled the LOG functions due to a bug in sdcc involving // vaargs. i = 100; // LOG(("i%%17 == 15 = %u\n", (int)(i%9))); ASSERT(i%17 == 15); // LOG(("i%%7 == 2 = %u\n", (int)i%7)); ASSERT(i%7 == 2); i = 49; // LOG(("i%%3 == 1 = %u\n", (int)i%3)); ASSERT(i%3 == 1); // LOG(("i%%5 == 4 = %u\n", (int)i%5)); ASSERT(i%5 == 4); } Fails on all but the first assert. Note that as all of the values are known sdcc optimises all of the calculations away. The common theme seems to be that the ones that fail involve a negative number.  Michael _______________________________________________ sdccdevel mailing list sdccdevel@... http://lists.sourceforge.net/lists/listinfo/sdccdevel 