5

In PHP, lets create a variable and set it value to 0:

$x = 0;
echo $x;

it would display 0. If one would multiply that by -1:

$x = -1 * $x;
echo $x;

we still see 0. But if $x is a float:

$x = 0;
$x = (float)$x;
$x = -1 * $x;
echo $x;

we would get the output: -0.

Why is that? Shouldn't zero be always displayed unsigned, regardless of its underlying type?

Gacek
  • 10,184
  • 9
  • 54
  • 87
  • 4
    Even more fun, try `$x = $x + 0` and printing again. The real reason is that PHP (and computers, in general really) may or may not actually represent any particular float with that exact value. Including zero. It's entirely possible that `-0` is really `-0.00000000000003` – CollinD Mar 16 '16 at 20:24
  • 2
    Main thing to get from this is that, you should never use `==` with floating numbers. – Gasim Mar 16 '16 at 20:25
  • 1
    dupe? http://stackoverflow.com/questions/588004/is-floating-point-math-broken –  Mar 16 '16 at 20:32

2 Answers2

1

Because PHP typically uses the IEEE 754 double precision format for floating point numbers which consists of:

1) sign (1 bit)

2) exponent (11 bit)

3) fraction (52 bit)

If you multiply $x with -1 the sign bit is set.

Integers use the two complement where the most significant bit (MSB) determines the sign. The MSB is 0 if you multiply with 0.

See: https://en.wikipedia.org/wiki/Signed_zero

Rocki
  • 363
  • 1
  • 2
  • 7
  • I don't think this answers the "Why" part of the question. The multiply by -1 changing the sign behavior does not apply to NaNs, and could have been defined not to apply to zero. – Patricia Shanahan Mar 17 '16 at 09:01
  • @PatriciaShanahan: I agree my answer misses use-cases for signed zeros but covers the technical side and php implementation. – Rocki Mar 17 '16 at 20:09
1

Floating point zero is used for more than just absolute zero. It is used to represent tiny results, too small absolute magnitude even for subnormal numbers.

In some calculations, the sign of such numbers does matter. For example, it matters that 1/+0 is positive infinity, but 1/-0 is negative infinity. To make that work right, multiplying 0 by -1 gives -0.

For example, See W. Kahan's paper "Branch Cuts for Complex Elementary Functions or Much Ado About Nothing's Sign Bit".

Patricia Shanahan
  • 25,849
  • 4
  • 38
  • 75
  • Yeah, but in PHP in most of the cases you don't control when suddenly int becomes float. And hence the problem with such unintended display. – Gacek Mar 16 '16 at 20:39
  • @Gacek PHP's rules for type conversion are complicated and occasionally silly, but they are entirely deterministic. You *do* "control" when an int becomes a float. – Sneftel Mar 17 '16 at 07:31