This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug middle-end/22072] bizarre code for int*int/2
- From: "pluto at agmk dot net" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 17 Jun 2005 00:53:16 -0000
- Subject: [Bug middle-end/22072] bizarre code for int*int/2
- References: <20050615060438.22072.felix-gcc@fefe.de>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Additional Comments From pluto at agmk dot net 2005-06-17 00:53 -------
(In reply to comment #7)
> (In reply to comment #6)
> > SAR r/m32, 1 Signed divide* r/m32 by 2, once
>
> Huh, I think that is wrong,
/*
* specifically, the division algorithm states that given
* two integers a and d, with d != 0, there exists unique
* integers q and r such that a = qd + r and 0 <= r < |d|,
* where |d| denotes the absolute value of d.
* the integer q is the quotient, r is the remainder,
* d is the divisor, and a is the dividend.
*
* examples:
*
* if a = 7 and d = 3, then q = 2 and r = 1.
* if a = 7 and d = -3, then q = -2 and r = 1.
* if a = -7 and d = 3, then q = -3 and r = 2.
* if a = -7 and d = -3, then q = 3 and r = 2.
*
*/
#include <stdio.h>
const int a[4] = { 5, -5 };
void div2_wrong(int* q, int*r, const int a)
{
*q = a / 2;
*r = a % 2;
}
void div2_correct(int* q, int*r, const int a)
{
*q = a >> 1;
*r = a - (*q << 1);
}
int main()
{
int i;
for (i = 0; i < 2; i++)
{
int q, r;
div2_wrong(&q, &r, a[i]);
printf("[w] a=%d, q=%d, r=%d\n", a[i], q, r);
div2_correct(&q, &r, a[i]);
printf("[c] a=%d, q=%d, r=%d\n", a[i], q, r);
}
return 0;
}
$ ./a.out (in this case d = 2)
[w] a= 5, q= 2, r= 1
[c] a= 5, q= 2, r= 1
[w] a=-5, q=-2, r=-1 <= wrong, vide 0 <= r < |d|
[c] a=-5, q=-3, r= 1
gcc div algorithm produces wrong result.
> (...) witness:
> #include <stdio.h>
> int f(int a)
> {
> return a >> 1;
> }
> int main(void)
> {
> int g = f(-5);
> printf("%d\n", g);
> }
>
> prints -3.
-3 looks fine.
a = -5, d = 2 -> q = -3, r = 1 -> qd+r = -3*2+1 = -5 = a.
did i miss something in my math?
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=22072