php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #53045 broken result of intval()
Submitted: 2010-10-12 18:34 UTC Modified: 2010-10-18 01:26 UTC
From: remy at wh dot nl Assigned:
Status: Not a bug Package: *Math Functions
PHP Version: 5.2.14 OS: FreeBSD
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: remy at wh dot nl
New email:
PHP Version: OS:

 

 [2010-10-12 18:34 UTC] remy at wh dot nl
Description:
------------
intval(log(8,2)) gives 2 as result, expected 3

Test script:
---------------
<?php
$maxrounds = log(8, 2);
echo 'test:'.$maxrounds."\n";
echo 'test:'.log(8,2)."\n";
echo 'intval:'.intval(3.0000)."\n";
echo 'intval:'.intval(log(8,2))."\n";
echo 'intval:'.intval($maxrounds)."\n";
echo 'intval+1:'.(intval($maxrounds)+1)."\n";
echo 'intval+1:'.intval($maxrounds+1)."\n";
echo 'intval+1:'.intval($maxrounds + 1)."\n";
echo 'sprintf dec:'.sprintf('%d', $maxrounds)."\n";
echo 'sprintf float:'.sprintf('%f', $maxrounds)."\n";
echo 'sprintf float non-locale:'.sprintf('%F', $maxrounds)."\n";
var_dump($maxrounds)."\n";
?>


Expected result:
----------------
test:3
test:3
intval:3
intval:3
intval:3
intval+1:4
intval+1:4
intval+1:4
sprintf dec:3
sprintf float:3.000000
sprintf float non-locale:3.000000
float(3)


Actual result:
--------------
test:3
test:3
intval:3
intval:2
intval:2
intval+1:3
intval+1:3
intval+1:3
sprintf dec:2
sprintf float:3.000000
sprintf float non-locale:3.000000
float(3)


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-10-12 19:06 UTC] rasmus@php.net
Only a problem on 32-bit systems I assume?  I can't reproduce it here, but all my 
stuff is 64-bit.
 [2010-10-12 19:30 UTC] remy at wh dot nl
Yes, 32bit, here is some hardware and OS info from sysctl:

kern.ostype: FreeBSD
kern.osrelease: 7.3-STABLE
kern.osrevision: 199506
kern.version: FreeBSD 7.3-STABLE #7: Thu Jul 15 20:09:49 CEST 2010
kern.maxvnodes: 100000
kern.maxproc: 6164
kern.maxfiles: 12328
kern.argmax: 262144
kern.securelevel: -1
kern.clockrate: { hz = 1000, tick = 1000, profhz = 2000, stathz = 133 }
kern.posix1version: 200112
kern.ngroups: 16
kern.job_control: 1
kern.saved_ids: 0
kern.boottime: { sec = 1281862574, usec = 963320 } Sun Aug 15 10:56:14 2010
kern.domainname:
kern.osreldate: 703100
kern.bootfile: /boot/kernel/kernel
kern.maxfilesperproc: 11095
kern.maxprocperuid: 5547
hw.machine: i386
hw.model: Intel(R) Pentium(R) 4 CPU 3.20GHz
hw.ncpu: 2
hw.byteorder: 1234
hw.physmem: 2134020096
hw.usermem: 1906421760
hw.pagesize: 4096
hw.floatingpoint: 1
hw.machine_arch: i386
hw.realmem: 2147155968
 [2010-10-12 19:33 UTC] remy at wh dot nl
CPU: Intel(R) Pentium(R) 4 CPU 3.20GHz (3211.39-MHz 686-class CPU)
  Origin = "GenuineIntel"  Id = 0xf43  Family = f  Model = 4  Stepping = 3
  Features=0xbfebfbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CLFLUSH,DT
S,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE>
  Features2=0x649d<SSE3,DTES64,MON,DS_CPL,EST,CNXT-ID,CX16,xTPR>
  AMD Features=0x20000000<LM>
  Logical CPUs per core: 2
 [2010-10-13 05:25 UTC] cataphract@php.net
-Status: Open +Status: Feedback
 [2010-10-13 05:25 UTC] cataphract@php.net
I can't reproduce on mipsel/32-bit/Linux, PHP 5.2.14.

Can you show us the result of this:

<?php
var_dump( unpack("H*",pack("d", 3.0000)) );
var_dump( unpack("H*",pack("d", log(8,2))) );

I get

array(1) {
  [1]=>
  string(16) "0000000000000840"
}
array(1) {
  [1]=>
  string(16) "0000000000000840"
}
 [2010-10-13 08:33 UTC] remy at wh dot nl
-Status: Feedback +Status: Open
 [2010-10-13 08:33 UTC] remy at wh dot nl
var_dump( unpack("H*",pack("d", 3.0000)) );
var_dump( unpack("H*",pack("d", log(8,2))) );

array(1) {
  [1]=>
  string(16) "0000000000000840"
}
array(1) {
  [1]=>
  string(16) "ffffffffffff0740"
}
 [2010-10-13 08:38 UTC] remy at wh dot nl
php -i output:

phpinfo()
PHP Version => 5.2.14

System => FreeBSD xxx.xxx.com 7.3-STABLE FreeBSD 7.3-STABLE #7: Thu Jul 15 20:09:49 CEST 2010     remy@xxx.xxx.com:/usr/obj/usr/src/sys/XXX i386
Build Date => Sep 22 2010 20:07:20
Configure Command =>  './configure'  '--with-libxml-dir=/usr/local/lib' '--with-config-file-path=/home/www/php' '--with-zlib' '--with-mysql' '--with-pgsql' '--enable-calendar' '--enable-mbstring' '--with-apxs2=/home/www/bin/apxs' '--enable-ftp' '--with-gd' '--enable-mbregex' '--enable-gd-native-ttf' '--with-png-dir=/usr/local/lib' '--with-jpeg-dir=/usr/local/lib' '--with-xpm-dir=/usr/X11R6/lib' '--with-freetype-dir=/usr/local/lib' '--with-iconv' '--with-curl' '--with-bz2'
 [2010-10-13 09:00 UTC] rasmus@php.net
Not sure there is a whole lot we can do about this.  It is a typical IEEE-754 
precision problem.  Try this simple C program, for example:

[a.c]
#include <stdio.h>
#include <math.h>
int main(int argc, char *argv[]) {
        printf("%.16f\n",log(8) / log(2));
}

LDFLAGS=-lm make a

./a

I get: 3.0000000000000000

I bet you get 2.9999999999999996
or something along those lines.

We might be able to do something clever with PHP's precision setting internally 
and round to that precision before doing the truncation there, but in reality 
you are dealing with floating point numbers here and whenever you deal with 
floating point numbers when programming you have to treat them as 
approximations, never as exact values.  Unless you are using arbitrary precision 
functions such as the gmp or bcmath function (which are orders of magnitude 
slower) you are going to have to account for these imprecisions in your code.
 [2010-10-13 09:30 UTC] remy at wh dot nl
[remy@xxx]~> cc -o a.test a.c -lm
[remy@xxx]~> ./a.test
2.9999999999999996

I'm not entirely sure, but I did not notice this problem in 5.2.12.
I'll try to recompile 5.2.12 to see if the problem occurred too...
 [2010-10-13 09:37 UTC] remy at wh dot nl
Ok, php 5.2.12 gives the same (broken) result...
 [2010-10-18 01:26 UTC] cataphract@php.net
-Status: Open +Status: Bogus
 [2010-10-18 01:26 UTC] cataphract@php.net
Closing as, most likely, this is not related to PHP.
 [2011-09-27 16:14 UTC] 282130106 at qq dot com
echo intval(pack('a*',log(8,2)));

or 

echo floor(pack('a*',log(8,2)));

It's gives 3,i don't now why.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 19:01:29 2024 UTC