php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #17772 array_merge() throws warning when supplied with 1 argument only
Submitted: 2002-06-15 10:10 UTC Modified: 2002-07-15 09:02 UTC
From: carlos at wfmh dot org dot pl Assigned:
Status: Not a bug Package: *Math Functions
PHP Version: 4.1.2 OS: Linux GNU/Debian
Private report: No CVE-ID: None
 [2002-06-15 10:10 UTC] carlos at wfmh dot org dot pl
round(12.555, 2) produces 12.55 not 12.56 as is documented (and as it should). round(12.556, 2) works fine thou.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2002-06-15 12:52 UTC] hholzgra@php.net
see the note on float precision on

http://www.php.net/manual/en/language.types.float.php
 [2002-07-15 08:54 UTC] george at intellnet dot net dot uk
No, 

This is a platform specific build/optimization issue not a float precision "bogus bug".  

Compile ext/standard/math.c without optimization i.e.
with -O0 instead of -O2, and the bug vanishes:

gcc -I. -I/home/george/php-4.2.1/ext/standard -I/home/george/php-4.2.1/main -I/home/george/php-4.2.1 -I/home/george/php-4.2.1/Zend -I/home/george/php-4.2.1/ext/mysql/libmysql -I/home/george/php-4.2.1/ext/xml/expat  -I/home/george/php-4.2.1/TSRM -g -O0  -c math.c && touch math.lo

(php 4.1.2 i386-pc-linux-gnu Debian Linux test 2.2.18pre21)

I believe BSD always works. 

For an even simpler test case, try round(0.35,1);

George
 [2002-07-15 09:02 UTC] carlos at wfmh dot org dot pl
So it's rather Makefile issue? Or it shall be reported to Debian package maintainer then?
 [2002-07-16 06:08 UTC] george at intellnet dot net dot uk
Switching off inline maths, (-D__NO_INLINE_MATHS), but leaving optimisation (-02), also solves this problem.

My guess as to what is going on is:

With inline maths, the value used on the floor() in round is coming straight from the fpu's register, not from memory. The register is wider than a double and contains spurious precision left over from the previous multiply, so the floor fp operation is carried out on the "wrong" number.  Without inline maths, the library floor() function is called so the operand comes out of the register and back into double format. 

This fits in with the observation that inserting trace or other code between the multiply and floor also solves the problem. 

If I'm right, the simple solution is to switch off in line maths, i.e. -D__NO_INLINE_MATHS.  For safety, this might need to be a general option across all compiles on Intel platforms. 

I'm going to try checking my diagnosis with a specialist newsgroup....


George Whiffen
 [2002-07-17 06:12 UTC] george at intellnet dot net dot uk
I checked the diagnosis on comp.lang.c and it's definitely a problem with values from the register.  We don't need -D__NO_MATH_INLINES,  -ffloat-store on the compile works fine.
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Mon Dec 16 04:01:27 2019 UTC