tinycc-devel
[Top][All Lists]
Advanced

[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)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]