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 -