[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Tinycc-devel] signed zero handling is still buggy
From: |
Vincent Lefevre |
Subject: |
[Tinycc-devel] signed zero handling is still buggy |
Date: |
Sun, 12 Jan 2014 01:49:10 +0100 |
User-agent: |
Mutt/1.5.21-6305-vl-r59709 (2013-04-16) |
On 2014-01-04 20:59:18 +0800, Thomas Preud'homme wrote:
> Le vendredi 3 janvier 2014, 13:28:13 Thomas Preud'homme a écrit :
> > Le vendredi 3 janvier 2014, 04:54:57 Vincent Lefevre a écrit :
> > > Hi Thomas,
> > >
> > > On 2014-01-03 10:30:15 +0800, Thomas Preud'homme wrote:
> > > > There is quite a few differences in the output about -0.0 where gcc
> > > > uses 0.0.
> > > > I'm not sure it's worth doing anything to change that since it's not
> > > > a bug but less divergence with gcc (and probably clang) could be
> > > > good. If it's just a few lines to add, why not. I might take a look
> > > > later this month, or never. ;)
> > >
> > > Actually I think that this is more than an output bug, but I don't
> > > know whether this is related. The fact is that tcc doesn't seem to
> > > support signed zeros (required by IEEE 754).
> >
> > Oh ok. I didn't look at the code that generated this output. Then I'll try
> > to take a look. Maybe not now but I'll keep it on my bug list.
>
> So I decided it could be an easy bug fix and it quite was so it's now fixed.
There's still a bug related to signed zero support.
I've updated my test:
static void signed_zero_inf (void)
{
double x = 0.0, y = -0.0, n, p;
printf ("\nSigned zero tests (x is 0.0 and y is -0.0):\n");
if (x == y)
printf ("Test 1.0 / x != 1.0 / y returns %d (should be 1).\n",
1.0 / x != 1.0 / y);
else
printf ("x != y; this is wrong!\n");
n = -x;
if (x == n)
printf ("Test 1.0 / x != 1.0 / -x returns %d (should be 1).\n",
1.0 / x != 1.0 / n);
else
printf ("x != -x; this is wrong!\n");
p = +y;
if (x == p)
printf ("Test 1.0 / x != 1.0 / +y returns %d (should be 1).\n",
1.0 / x != 1.0 / p);
else
printf ("x != +y; this is wrong!\n");
}
I get:
Signed zero tests (x is 0.0 and y is -0.0):
Test 1.0 / x != 1.0 / y returns 1 (should be 1).
Test 1.0 / x != 1.0 / -x returns 0 (should be 1).
Test 1.0 / x != 1.0 / +y returns 0 (should be 1).
Note that -x (resp. +x) is not equivalent to 0-x (resp. 0+x).
If I understand the code generated by GCC for -x, it changes the
sign bit with xorpd. This follows the IEEE 754-2008 standard:
negate(x) copies a floating-point operand x to a destination in the
same format, reversing the sign bit. negate(x) is not the same as
subtraction(0, x) (see 6.3).
The C99 standard says:
The result of the unary + operator is the value of its (promoted)
operand. The integer promotions are performed on the operand, and
the result has the promoted type.
The result of the unary - operator is the negative of its (promoted)
operand. The integer promotions are performed on the operand, and
the result has the promoted type.
So, it seems that a unary + (when used in a valid context) is just a
no-op (I suppose that the only difference is when it is an argument
of the sizeof operator).
--
Vincent Lefèvre <address@hidden> - Web: <http://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)