Bug #73358 [Opn]: $array[245.999] truncates the index (245) instead of rounding it (246)

From: Date: Thu, 20 Oct 2016 16:26:23 +0000
Subject: Bug #73358 [Opn]: $array[245.999] truncates the index (245) instead of rounding it (246)
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-204937@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=73358&edit=1 ID: 73358 Updated by: requinix@php.net Reported by: x-alexander93 at yandex dot ru -Summary: Bug with float to int conversion +Summary: $array[245.999] truncates the index (245) instead of rounding it (246) Status: Open Type: Bug -Package: *General Issues +Package: Arrays related Operating System: Debian 8.6, Windows 7 PHP Version: 5.6.27 Block user comment: N Private report: N New Comment: Floating point values have a limited precision. Hence a value might not have the same string representation after any processing. That also includes writing a floating point value in your script and directly printing it without any mathematical operations. If you would like to know more about "floats" and what IEEE 754 is, read this: http://www.floating-point-gui.de/ Thank you for your interest in PHP. https://3v4l.org/lF8P9 8.2 * 30 is not 246 but a tiny bit less than that: 245.999999ish. This is typical of arithmetic with floating-point values and occurs in languages besides PHP. In PHP, numbers with fractional parts are not supported as array indices. If you try to use them then they will be treated as integers - truncating the floating-point value to just the integral part. Thus $a[245.999999] is treated as $a[245] and that will appear in your array when you didn't expect it. The "tiny bit less" remains true until 256 (255.999999....), after which the representation changes and either (a) it becomes integral or (b) it is slightly *more* than the expected value and the difference is beyond the precision=20 set in that example script. I'm guessing the former. This effectively skips the 256 index. The moral is to round() calculated values to a reasonable precision as warranted by your application. Rounding $from and $too is the easiest option. $from = round("8.2" * "30"); // expecting an integer so round to 0 decimal digits $to = round("11.4" * "30"); With that said, there is an opportunity for PHP's behavior to change: round floating-point array indices instead of truncating them. Personally I think that's a good idea but I'll leave the decision to someone else. Previous Comments: ------------------------------------------------------------------------ [2016-10-20 15:49:02] x-alexander93 at yandex dot ru Description: ------------ Hi! I've found a bug with (possible?) float to int conversion. Well, I don't know to which category it could be more closely related. I found the same results on Debian 8.6, CentOS 7 (with the latest 5.6 version from remi repo) and on the old XAMPP install with PHP 5.5 under Windows 7. No PEAR or PECL packets were installed. Everything from standard PHP library (like imagick etc). Here is the result of test script execution: http://pastebin.com/JWJby27F Test script: --------------- <?php // from 246 $from = "8.2" * "30"; // to 342 $to = "11.4" * "30"; $a = []; for ($i = $from; $i <= $to; $i++) { if ($i == 246) { echo "No output at all!"; } if ($i == 250) { echo "Still no output..."; } if ($i == 256) { echo "Still no output..."; } if ($i == 257) { echo "It works for {$i} and further numbers"; } var_dump($i); $a[$i] = "test" . $i; } var_dump($a); // array index number doesn't match the assigned value number (despite $i is a float without a fractional part) // also there is no element with index 256 in the $a array... Expected result: ---------------- 1)Equality operator should return true for all numbers within $from..$to range 2)Array indexes should not be skipped during assigment Actual result: -------------- 1)Equality operator returns false on ($i == number) when number is lower than 257. 2)Array index number doesn't match the assigned $i value number 3)Index with number 256 was missed at all in the $a array ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=73358&edit=1

« previous php.bugs (#204937) next »