I have been compiling PHP under various compilers trying to figure out
what flags I need for each compiler to pass all tests excluding
XFAILs. With Intel 13.0.1 I'm down to two failing tests:
=====================================================================
FAILED TEST SUMMARY
Test fmod()
- basic function test fmod()
[ext/standard/tests/math/fmod_basic.phpt]
Test fmod function : 64bit long tests
[ext/standard/tests/math/fmod_basiclong_64bit.phpt]
The only differences are between -0 and 0 (exact diffs at end of message).
My understanding of floating point calculations is that -0 and 0 are
equivalent, so I can safely ignore the failures. I wanted to first
check to make sure that is actually true.
Assuming that the above is correct, I wanted to patch the phpt files
for the tests to pass. However, I'm not very familiar with that
format. How would you suggest altering the tests to make this pass?
cat ext/standard/tests/math/fmod_basic.diff
016+ float(0)
017+ float(0)
016- float(-0)
017- float(-0)
020+ float(0)
021+ float(0)
022+ float(0)
020- float(-0)
021- float(-0)
022- float(-0)
026+ float(0)
026- float(-0)
cat ext/standard/tests/math/fmod_basiclong_64bit.diff
026+ float(0)
026- float(-0)
028+ float(0)
028- float(-0)
040+ float(0)
040- float(-0)
042+ float(0)
042- float(-0)
044+ float(0)
044- float(-0)
070+ float(0)
070- float(-0)
072+ float(0)
072- float(-0)
084+ float(0)
084- float(-0)
114+ float(0)
114- float(-0)
116+ float(0)
116- float(-0)
128+ float(0)
128- float(-0)
158+ float(0)
158- float(-0)
160+ float(0)
160- float(-0)
290+ float(0)
290- float(-0)
292+ float(0)
292- float(-0)
304+ float(0)
304- float(-0)
306+ float(0)
306- float(-0)
308+ float(0)
308- float(-0)
312+ float(0)
312- float(-0)
314+ float(0)
314- float(-0)
326+ float(0)
326- float(-0)
328+ float(0)
328- float(-0)
330+ float(0)
330- float(-0)
I have been compiling PHP under various compilers trying to figure out
what flags I need for each compiler to pass all tests excluding
XFAILs. With Intel 13.0.1 I'm down to two failing tests:=====================================================================
FAILED TEST SUMMARYTest
fmod()
- basic function testfmod()
[ext/standard/tests/math/fmod_basic.phpt]
Test fmod function : 64bit long tests
[ext/standard/tests/math/fmod_basiclong_64bit.phpt]The only differences are between -0 and 0 (exact diffs at end of
message).My understanding of floating point calculations is that -0 and 0 are
equivalent, so I can safely ignore the failures. I wanted to first
check to make sure that is actually true.
No, they are not the same thing for several purposes. For instance, they
have different serializations. See also:
$ php
<?php $nz = fmod(-2,2); var_dump(atan2(0., $nz), atan2($nz, $nz));
float(3.1415926535898)
float(-3.1415926535898)
So I think you should investigate the cause of the problem (different
results), rather than ignoring the differences. Possibly the difference
lies in the Intel math library; in that case, you can either separate the
tests in two or just ignore the test when compiling with the Intel
compiler.
Assuming that the above is correct, I wanted to patch the phpt files
for the tests to pass. However, I'm not very familiar with that
format. How would you suggest altering the tests to make this pass?
Check these:
http://qa.php.net/write-test.php
http://qa.php.net/phpt_details.php
You can also inspect the file run-tests.php if you have any doubt.
--
Gustavo Lopes
My understanding of floating point calculations is that -0 and 0 are
equivalent, so I can safely ignore the failures. I wanted to first
check to make sure that is actually true.No, they are not the same thing for several purposes. For instance, they
have different serializations. See also:$ php
<?php $nz = fmod(-2,2); var_dump(atan2(0., $nz), atan2($nz, $nz));
float(3.1415926535898)
float(-3.1415926535898)So I think you should investigate the cause of the problem (different
results), rather than ignoring the differences. Possibly the difference lies
in the Intel math library; in that case, you can either separate the tests
in two or just ignore the test when compiling with the Intel compiler.
Are the rules for double-precision floats the same in this regard?
I have confirmed that fmod(-2, 2) returns positive zero in icc. I have
asked on their forum if there is a flag or something I can enable to
fix this; it might be a bug. Note that fmodf (for floats, not
doubles) correctly returns -0.
On Tue, 05 Feb 2013 00:12:54 +0100, Levi Morrison
morrison.levi@gmail.com wrote:
I have confirmed that fmod(-2, 2) returns positive zero in icc. I have
asked on their forum if there is a flag or something I can enable to
fix this; it might be a bug. Note that fmodf (for floats, not
doubles) correctly returns -0.
I checked C99 and what it says about this is (7.12.10.1 §3): «The fmod
functions return the value x -ny, for some integer n such that, if y is
nonzero, the result has the same sign as x...»
We can takes clues about whether the sign comment applies to zeros here in
5.4.2.2 §4:
«An implementation may give zero and non-numeric values (such as
infinities and NaNs) a sign or may leave them unsigned. Wherever such
values are unsigned, any requirement in this International Standard to
retrieve the sign shall produce an unspecified sign, and any requirement
to set the sign shall be ignored.»
This would suggest that the sign requirement DOES apply as long as
positive and negative zeros exist. While that doesn't follow logically
(the last sentence applies to when the values are unsigned), we can follow
the principle of "the exception that proves the rule".
Therefore, I would be inclined to suggest that this is indeed a bug in
math library, but this was just a quick check (may depend on which
standards and which versions are followed, etc).
--
Gustavo Lopes
I have a confirmed bug with Intel Engineering. For clarification
purposes here, it only happens on 64-bit bit versions of icc and
possibly only on Linux. If you link against the math library using
-lm
then this goes away at the cost of performance (though a
negligible cost I would guess).
Thanks for all the responses!
I have been compiling PHP under various compilers trying to figure out
what flags I need for each compiler to pass all tests excluding
XFAILs. With Intel 13.0.1 I'm down to two failing tests:=====================================================================
FAILED TEST SUMMARYTest
fmod()
- basic function testfmod()
[ext/standard/tests/math/fmod_basic.phpt]
Test fmod function : 64bit long tests
[ext/standard/tests/math/fmod_basiclong_64bit.phpt]The only differences are between -0 and 0 (exact diffs at end of message).
My understanding of floating point calculations is that -0 and 0 are
equivalent, so I can safely ignore the failures. I wanted to first
check to make sure that is actually true.Assuming that the above is correct, I wanted to patch the phpt files
for the tests to pass. However, I'm not very familiar with that
format. How would you suggest altering the tests to make this pass?
cat ext/standard/tests/math/fmod_basic.diff
016+ float(0)
017+ float(0)
016- float(-0)
017- float(-0)
020+ float(0)
021+ float(0)
022+ float(0)
020- float(-0)
021- float(-0)
022- float(-0)
026+ float(0)
026- float(-0)cat ext/standard/tests/math/fmod_basiclong_64bit.diff
026+ float(0)
026- float(-0)
028+ float(0)
028- float(-0)
040+ float(0)
040- float(-0)
042+ float(0)
042- float(-0)
044+ float(0)
044- float(-0)
070+ float(0)
070- float(-0)
072+ float(0)
072- float(-0)
084+ float(0)
084- float(-0)
114+ float(0)
114- float(-0)
116+ float(0)
116- float(-0)
128+ float(0)
128- float(-0)
158+ float(0)
158- float(-0)
160+ float(0)
160- float(-0)
290+ float(0)
290- float(-0)
292+ float(0)
292- float(-0)
304+ float(0)
304- float(-0)
306+ float(0)
306- float(-0)
308+ float(0)
308- float(-0)
312+ float(0)
312- float(-0)
314+ float(0)
314- float(-0)
326+ float(0)
326- float(-0)
328+ float(0)
328- float(-0)
330+ float(0)
330- float(-0)--
hi,
you could use EXPECTREGEX (
http://qa.php.net/phpt_details.php#expectregex_section) with something like
float([+-]*0)
--
Ferenc Kovács
@Tyr43l - http://tyrael.hu