|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[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)
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Fri Oct 24 16:00:02 2025 UTC |
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: 2147155968I 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" }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" }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.echo intval(pack('a*',log(8,2))); or echo floor(pack('a*',log(8,2))); It's gives 3,i don't now why.