delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2003/04/22/07:45:08

From: Ben Peddell <killer DOT lightspeed AT bigpond DOT com>
User-Agent: Mozilla/5.0 (X11; U; Linux i586; en-US; rv:1.1) Gecko/20020826
X-Accept-Language: en-us, en
MIME-Version: 1.0
Newsgroups: comp.os.msdos.djgpp
Subject: Re: Bug 00314 -- div() still broken
References: <3e9c6920$0$21928$afc38c87@>
Lines: 137
Message-ID: <fA9pa.20115$1s1.299825@newsfeeds.bigpond.com>
Date: Tue, 22 Apr 2003 21:30:36 +1000
NNTP-Posting-Host: 144.139.175.108
X-Trace: newsfeeds.bigpond.com 1051010443 144.139.175.108 (Tue, 22 Apr 2003 21:20:43 EST)
NNTP-Posting-Date: Tue, 22 Apr 2003 21:20:43 EST
Organization: Telstra BigPond Internet Services (http://www.bigpond.com)
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

Eric Rudd wrote:
> On 2000-01-18, I submitted bug report 00314, which concerns incorrect 
> behavior of the div() and ldiv() functions.  The DJGPP bug-tracking 
> system reports this bug as being fixed, but the latest source appears to 
> be still unchanged from before, and moreover a call to div() in the 
> libc.a dated 2001-12-24 from gcc 3.2.2-compiled code now bombs:
> 
> #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;
> }
> 
> 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
> 
> If I re-compile and link in div.c as extracted from djdev203.zip, the 
> code completes, but with the incorrect answer
> 
>  -13, -1
> 
> instead of the correct answer
> 
>   -13, 1.
> 
> There are evidently at least two problems here: 1) the source in div.c 
> and ldiv.c didn't get fixed, contrary to what the entries for bug report 
> 00314 seem to indicate; 2) there is some corruption or incompatibility 
> of the binary in libc.a.  Since my efforts to get this div() bug fixed 
> through the bug-tracking system have been unsuccessful, I am posting 
> this to the newsgroup.  If others are able to reproduce these bugs, so 
> that I know I'm not just doing something stupid, I can submit source 
> code that fixes them, but I already did that in bug report 00314, so I 
> don't know what more to do.
> 
> -Eric Rudd
> rudd AT cyberoptics DOT com
> 

 From your crash, it looks like the divide was being called something like:
result = div(-3,-3);

Here's the source that I compiled under Mandrake 9.0 with GCC 3.2:

==== Start of source file ====
#include <stdio.h>
#include <stdlib.h>

/*
  * This is compiled under Mandrake 9.0 with GCC 3.2
  */

/*
  * The source of div() in DJGPP
  */
div_t dj_div(int num, int denom){
   div_t r;

   if (num > 0 && denom < 0) {
     num = -num;
     denom = -denom;
   }
   r.quot = num / denom;
   r.rem = num % denom;
   if (num < 0 && denom > 0)
   {
     if (r.rem > 0)
     {
       r.quot++;
       r.rem -= denom;
     }
   }
   return r;
}

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

   /* The div() contained in Mandrake's libc */
   result = div(a, b);
   printf("Linux div(%d,%d) = %d, %d\n", a, b, result.quot, result.rem);

   /* div() in assembly */
   asm (
       "idiv %3"
       : "=a" (result.quot), "=d" (result.rem)
       : "a" (a), "r" (b), "d" (0)
   );
   printf("Asm   div(%d,%d) = %d, %d\n", a, b, result.quot, result.rem);

   /* div() in c */
   result.quot = a / b;
   result.rem = a % b;
   printf("C     div(%d,%d) = %d, %d\n", a, b, result.quot, result.rem);

   /* a call to DJGPP's div() */
   result = dj_div(a, b);
   printf("DJGPP div(%d,%d) = %d, %d\n", a, b, result.quot, result.rem);
   return 0;
}

==== End of source file ====

And the results:

Linux div(40,-3) = -13, 1
Asm   div(40,-3) = -13, 1
C     div(40,-3) = -13, 1
DJGPP div(40,-3) = -13, -1

I think you can see the odd one out.

By the way, the libc reference in DJGPP says that the DJGPP result is 
correct.

- Raw text -


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