Bug 000314

When Created: 01/18/2000 13:00:50
Against DJGPP version: 2.03
By whom:
Abstract: div(40,-3) and ldiv(40,-3) return incorrect remainder sign
div(numer,denom) and ldiv(numer,denom), where numer>0 and denom<0, return
negative remainders, whereas the remainders should be positive in such a
situation.  ANSI specifies that quot*denom + rem shall equal numer, which it
therefore does not.

Solution added: 01/18/2000 13:00:21
By whom:
The existing source code tries too hard to handle the various sign possibilities
for the two arguments.  The second conditional in the existing code is intended
to fix up the result in case the machine truncates the quotient towards
-infinity, instead of towards zero, but this conditional is never taken in
DJGPP, since DJGPP always returns an integer quotient truncated toward zero.
Thus, it appears that no tests at all are needed when running the code under
DJGPP.  Here is my suggested solution for div.c:

/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
#include <stdlib.h>

div(int num, int denom)
  div_t r;

  r.rem = num % denom;
  r.quot = num / denom;

  return r;

The fix for ldiv.c is similar.  Note that I also took the liberty of re-ordering
the statements -- this seemed to please the optimizer, which otherwise
generated much useless data motion.  The optimizer is, however, smart enough to
do only one idiv, so assembly language is probably not needed here.

Fixed in version on 07/07/2000 20:23:59
By whom:

Note added: 03/18/2003 10:27:10
By whom:
I have still this problem!!.

I am ussing the next versions: bnu213b, djdev203, faq230b, fil41b,
gcc32b, ntlfn08b, pakk022b, rhid149b, txi42b and zipo020b.

Which ones files I need updated?.

   V. Garcia

PS. I have tried to use other new versions of software (like: djdev203,
faq230b, pakk022b, zipo020b, rhide15b, bnu213b, fil41b, gcc322b, gdb53b,
mak3791b, ntlfn08b, ... ) but, I think, LDIV doesn´t work properly!.

Note added: 04/15/2003 15:49:08
By whom:
div() seems to be even more badly broken than before.  Using the libc.a in, dated 2001-12-24, gcc 3.2.2, and this little test app

#include <stdio.h>
#include <stdlib.h>

int main(void) {
   div_t result;
   int a = 40, b = -3;

   result = div(a, b);
   printf("div(%d,%d) = %d, %d\n", a, b, result.quot, result.rem);
   return 0;

the code bombs:

Exiting due to signal SIGFPE 
Division by Zero at eip=00003371, x87 status=0000
eax=fffffffd ebx=fffffffd ecx=00000000 edx=ffffffff esi=00000054 edi=00000028
ebp=0008fb18 esp=0008fb04 program=C:\XFER\DIVTST.EXE
cs: sel=00f7  base=87608000  limit=0009ffff
ds: sel=00ff  base=87608000  limit=0009ffff
es: sel=00ff  base=87608000  limit=0009ffff
fs: sel=00d7  base=0001efc0  limit=0000ffff
gs: sel=010f  base=00000000  limit=0010ffff
ss: sel=00ff  base=87608000  limit=0009ffff
App stack: [0008fb5c..0000fb5c]  Exceptn stack: [0000faac..0000db6c]

Call frame traceback EIPs:
  0x00003371 div+33, file div.c
  0x00001703 main+19, file c:/xfer/divtst.c, line 9
  0x00003348 __crt1_startup+176, file crt1.c

when I re-compile from div.c source, it doesn't bomb, but still gives the wrong answers.

  webmaster     delorie software   privacy  
  Copyright © 2010   by DJ Delorie     Updated Jul 2010