php - PHP中两个相等的数字怎么可能不相等

原文 标签 php

How could two equal numbers not be equal in PHP

I have two numbers which are supposed to be equal to return a difference, I doesn't make sense...

The only way to be able to reproduce this problem here I had to base64_encode my arrays,

here is the script:

basically the script will fix numbers like "1 234,5" to "1234.5" and does calculations, but at the ends it returns

            First Number: 4784.47
            Second Number: 4784.47
            Difference: 9.0949470177293E-13

I just don't understand????????


            $aa = 'YTo3OntpOjA7YToxMDp7czoxMToiRGVzY3JpcHRpb24iO3M6MTI6IkvDqWsgc3rDoW1vayI7czo2OiJQZXJpb2QiO3M6MTI6IjA4LjEwLTA4LjEwLiI7czo2OiJBbW91bnQiO3M6MToiMSI7czoxMjoiRHVyYXRpb25UaW1lIjtzOjc6IjA6MDQ6MDAiO3M6MTI6Ik5ldFVuaXRQcmljZSI7czo1OiIzNSwyMCI7czo5OiJOZXRBbW91bnQiO3M6NjoiMTQwLDgwIjtzOjEwOiJWQVRQZXJjZW50IjtzOjM6IjI1JSI7czozOiJWQVQiO3M6NToiMzUsMjAiO3M6MTE6Ikdyb3NzQW1vdW50IjtzOjY6IjE3NiwwMCI7czo4OiJJdGVtQ29kZSI7czo0OiJCTFVFIjt9aToxO2E6MTA6e3M6MTE6IkRlc2NyaXB0aW9uIjtzOjE3OiJCZWxmw7ZsZGkgaMOtdsOhcyI7czo2OiJQZXJpb2QiO3M6MTI6IjA3LjIyLTA4LjExLiI7czo2OiJBbW91bnQiO3M6MjoiMTIiO3M6MTI6IkR1cmF0aW9uVGltZSI7czo3OiIwOjIxOjQzIjtzOjEyOiJOZXRVbml0UHJpY2UiO3M6NToiMTUsMjAiO3M6OToiTmV0QW1vdW50IjtzOjY6IjMzMCwxMCI7czoxMDoiVkFUUGVyY2VudCI7czozOiIyNSUiO3M6MzoiVkFUIjtzOjU6IjgyLDUyIjtzOjExOiJHcm9zc0Ftb3VudCI7czo2OiI0MTIsNjIiO3M6ODoiSXRlbUNvZGUiO3M6ODoiRklYX0ZMQVQiO31pOjI7YToxMDp7czoxMToiRGVzY3JpcHRpb24iO3M6MjM6IkVnecOpYiBtb2JpbCBlZ3lzw6lnw6FyIjtzOjY6IlBlcmlvZCI7czoxMjoiMDcuMjEtMDguMTEuIjtzOjY6IkFtb3VudCI7czoyOiI1MCI7czoxMjoiRHVyYXRpb25UaW1lIjtzOjc6IjE6MDE6MzgiO3M6MTI6Ik5ldFVuaXRQcmljZSI7czo1OiIxNSwyMCI7czo5OiJOZXRBbW91bnQiO3M6NjoiOTM2LDgzIjtzOjEwOiJWQVRQZXJjZW50IjtzOjM6IjI1JSI7czozOiJWQVQiO3M6NjoiMjM0LDIxIjtzOjExOiJHcm9zc0Ftb3VudCI7czo4OiIxIDE3MSwwNCI7czo4OiJJdGVtQ29kZSI7czo4OiJPRkZfRkxBVCI7fWk6MzthOjEwOntzOjExOiJEZXNjcmlwdGlvbiI7czoxOToiVm9kYWZvbmUgZWd5c8OpZ8OhciI7czo2OiJQZXJpb2QiO3M6MTI6IjA3LjE1LTA4LjEyLiI7czo2OiJBbW91bnQiO3M6MjoiMjAiO3M6MTI6IkR1cmF0aW9uVGltZSI7czo3OiIwOjU0OjM3IjtzOjEyOiJOZXRVbml0UHJpY2UiO3M6NToiMTUsMjAiO3M6OToiTmV0QW1vdW50IjtzOjY6Ijc2MywwNSI7czoxMDoiVkFUUGVyY2VudCI7czozOiIyNSUiO3M6MzoiVkFUIjtzOjY6IjE5MCw3NiI7czoxMToiR3Jvc3NBbW91bnQiO3M6NjoiOTUzLDgxIjtzOjg6Ikl0ZW1Db2RlIjtzOjc6Ik9OX0ZMQVQiO31pOjQ7YToxMDp7czoxMToiRGVzY3JpcHRpb24iO3M6MTU6Ik5lbXpldGvDtnppIFNNUyI7czo2OiJQZXJpb2QiO3M6MTI6IjA3LjEzLTA4LjEzLiI7czo2OiJBbW91bnQiO3M6MjoiNDIiO3M6MTI6IkR1cmF0aW9uVGltZSI7czoxOiItIjtzOjEyOiJOZXRVbml0UHJpY2UiO3M6NToiMzAsNDAiO3M6OToiTmV0QW1vdW50IjtzOjg6IjEgMjc2LDgwIjtzOjEwOiJWQVRQZXJjZW50IjtzOjM6IjI1JSI7czozOiJWQVQiO3M6NjoiMzE5LDIwIjtzOjExOiJHcm9zc0Ftb3VudCI7czo4OiIxIDU5NiwwMCI7czo4OiJJdGVtQ29kZSI7czo3OiJTTVNfSU5UIjt9aTo1O2E6MTA6e3M6MTE6IkRlc2NyaXB0aW9uIjtzOjIzOiJTTVMgaMOhbMOzemF0b24ga8OtdsO8bCI7czo2OiJQZXJpb2QiO3M6MTI6IjA3LjI1LTA4LjExLiI7czo2OiJBbW91bnQiO3M6MjoiMTUiO3M6MTI6IkR1cmF0aW9uVGltZSI7czoxOiItIjtzOjEyOiJOZXRVbml0UHJpY2UiO3M6NToiMTUsMjAiO3M6OToiTmV0QW1vdW50IjtzOjY6IjIyOCwwMCI7czoxMDoiVkFUUGVyY2VudCI7czozOiIyNSUiO3M6MzoiVkFUIjtzOjU6IjU3LDAwIjtzOjExOiJHcm9zc0Ftb3VudCI7czo2OiIyODUsMDAiO3M6ODoiSXRlbUNvZGUiO3M6NzoiU01TX09GRiI7fWk6NjthOjEwOntzOjExOiJEZXNjcmlwdGlvbiI7czoyMjoiU01TIGjDoWzDs3phdG9uIGJlbMO8bCI7czo2OiJQZXJpb2QiO3M6MTI6IjA3LjE3LTA4LjEyLiI7czo2OiJBbW91bnQiO3M6MjoiMTUiO3M6MTI6IkR1cmF0aW9uVGltZSI7czoxOiItIjtzOjEyOiJOZXRVbml0UHJpY2UiO3M6NToiMTUsMjAiO3M6OToiTmV0QW1vdW50IjtzOjY6IjE1MiwwMCI7czoxMDoiVkFUUGVyY2VudCI7czozOiIyNSUiO3M6MzoiVkFUIjtzOjU6IjM4LDAwIjtzOjExOiJHcm9zc0Ftb3VudCI7czo2OiIxOTAsMDAiO3M6ODoiSXRlbUNvZGUiO3M6NjoiU01TX09OIjt9fQ==';

            $tt = 'YTozOntzOjE2OiJTdW1tYXJ5SXRlbU5ldHRvIjtzOjg6IjMgODI3LDU4IjtzOjE0OiJTdW1tYXJ5SXRlbVZBVCI7czo2OiI5NTYsODkiO3M6MTc6IlN1bW1hcnlJdGVtQnJ1dHRvIjtzOjg6IjQgNzg0LDQ3Ijt9';

            $a = unserialize(base64_decode($aa));
            $t = unserialize(base64_decode($tt));


            function calculate_call_fees($a,$t){

                $or_item = 0;

                foreach($a as $k => $r) {
                    $or_item += fix_num($r['GrossAmount']); 
                }        

                $br =  fix_num($t['SummaryItemBrutto']);   

                if($br>$or_item){
                    $diff = $br-$or_item;
                } else {
                    $diff = 0;
                }

                echo 'First Number: ' . $br.'<br/>';
                echo 'Second Number: ' . $or_item.'<br />';
                echo 'Difference: ' . $diff.'<br />';

                echo '<hr />';
                echo '<pre>';
                print_r($a);
                echo '</pre>';
                echo '<hr />';
                echo '<pre>';
                print_r($t);
                echo '</pre>';    

            }

            function fix_num($n){
                return floatval(str_replace(Array(" ",","),array("","."),$n));
            }

            calculate_call_fees($a,$t);
Answer

Using "equals" comparison with floating point numbers is dangerous because of floating point limited precision - you're liable to get small differences due to the rounding involved.

Instead, if you want to see if two floating point numbers are "the same", just see if their difference is below a certain threshold:

if( abs($a - $b) < 0.00000001) {
    // a and b are "equal"
}

翻译

我有两个本应等于返回差值的数字,我没有道理...

在这里能够重现此问题的唯一方法是我必须对数组进行base64_encode,

这是脚本:

基本上,脚本会将数字“ 1 234,5”固定为“ 1234.5”并进行计算,但最后返回

            First Number: 4784.47
            Second Number: 4784.47
            Difference: 9.0949470177293E-13


我只是不明白????????



            $aa = 'YTo3OntpOjA7YToxMDp7czoxMToiRGVzY3JpcHRpb24iO3M6MTI6IkvDqWsgc3rDoW1vayI7czo2OiJQZXJpb2QiO3M6MTI6IjA4LjEwLTA4LjEwLiI7czo2OiJBbW91bnQiO3M6MToiMSI7czoxMjoiRHVyYXRpb25UaW1lIjtzOjc6IjA6MDQ6MDAiO3M6MTI6Ik5ldFVuaXRQcmljZSI7czo1OiIzNSwyMCI7czo5OiJOZXRBbW91bnQiO3M6NjoiMTQwLDgwIjtzOjEwOiJWQVRQZXJjZW50IjtzOjM6IjI1JSI7czozOiJWQVQiO3M6NToiMzUsMjAiO3M6MTE6Ikdyb3NzQW1vdW50IjtzOjY6IjE3NiwwMCI7czo4OiJJdGVtQ29kZSI7czo0OiJCTFVFIjt9aToxO2E6MTA6e3M6MTE6IkRlc2NyaXB0aW9uIjtzOjE3OiJCZWxmw7ZsZGkgaMOtdsOhcyI7czo2OiJQZXJpb2QiO3M6MTI6IjA3LjIyLTA4LjExLiI7czo2OiJBbW91bnQiO3M6MjoiMTIiO3M6MTI6IkR1cmF0aW9uVGltZSI7czo3OiIwOjIxOjQzIjtzOjEyOiJOZXRVbml0UHJpY2UiO3M6NToiMTUsMjAiO3M6OToiTmV0QW1vdW50IjtzOjY6IjMzMCwxMCI7czoxMDoiVkFUUGVyY2VudCI7czozOiIyNSUiO3M6MzoiVkFUIjtzOjU6IjgyLDUyIjtzOjExOiJHcm9zc0Ftb3VudCI7czo2OiI0MTIsNjIiO3M6ODoiSXRlbUNvZGUiO3M6ODoiRklYX0ZMQVQiO31pOjI7YToxMDp7czoxMToiRGVzY3JpcHRpb24iO3M6MjM6IkVnecOpYiBtb2JpbCBlZ3lzw6lnw6FyIjtzOjY6IlBlcmlvZCI7czoxMjoiMDcuMjEtMDguMTEuIjtzOjY6IkFtb3VudCI7czoyOiI1MCI7czoxMjoiRHVyYXRpb25UaW1lIjtzOjc6IjE6MDE6MzgiO3M6MTI6Ik5ldFVuaXRQcmljZSI7czo1OiIxNSwyMCI7czo5OiJOZXRBbW91bnQiO3M6NjoiOTM2LDgzIjtzOjEwOiJWQVRQZXJjZW50IjtzOjM6IjI1JSI7czozOiJWQVQiO3M6NjoiMjM0LDIxIjtzOjExOiJHcm9zc0Ftb3VudCI7czo4OiIxIDE3MSwwNCI7czo4OiJJdGVtQ29kZSI7czo4OiJPRkZfRkxBVCI7fWk6MzthOjEwOntzOjExOiJEZXNjcmlwdGlvbiI7czoxOToiVm9kYWZvbmUgZWd5c8OpZ8OhciI7czo2OiJQZXJpb2QiO3M6MTI6IjA3LjE1LTA4LjEyLiI7czo2OiJBbW91bnQiO3M6MjoiMjAiO3M6MTI6IkR1cmF0aW9uVGltZSI7czo3OiIwOjU0OjM3IjtzOjEyOiJOZXRVbml0UHJpY2UiO3M6NToiMTUsMjAiO3M6OToiTmV0QW1vdW50IjtzOjY6Ijc2MywwNSI7czoxMDoiVkFUUGVyY2VudCI7czozOiIyNSUiO3M6MzoiVkFUIjtzOjY6IjE5MCw3NiI7czoxMToiR3Jvc3NBbW91bnQiO3M6NjoiOTUzLDgxIjtzOjg6Ikl0ZW1Db2RlIjtzOjc6Ik9OX0ZMQVQiO31pOjQ7YToxMDp7czoxMToiRGVzY3JpcHRpb24iO3M6MTU6Ik5lbXpldGvDtnppIFNNUyI7czo2OiJQZXJpb2QiO3M6MTI6IjA3LjEzLTA4LjEzLiI7czo2OiJBbW91bnQiO3M6MjoiNDIiO3M6MTI6IkR1cmF0aW9uVGltZSI7czoxOiItIjtzOjEyOiJOZXRVbml0UHJpY2UiO3M6NToiMzAsNDAiO3M6OToiTmV0QW1vdW50IjtzOjg6IjEgMjc2LDgwIjtzOjEwOiJWQVRQZXJjZW50IjtzOjM6IjI1JSI7czozOiJWQVQiO3M6NjoiMzE5LDIwIjtzOjExOiJHcm9zc0Ftb3VudCI7czo4OiIxIDU5NiwwMCI7czo4OiJJdGVtQ29kZSI7czo3OiJTTVNfSU5UIjt9aTo1O2E6MTA6e3M6MTE6IkRlc2NyaXB0aW9uIjtzOjIzOiJTTVMgaMOhbMOzemF0b24ga8OtdsO8bCI7czo2OiJQZXJpb2QiO3M6MTI6IjA3LjI1LTA4LjExLiI7czo2OiJBbW91bnQiO3M6MjoiMTUiO3M6MTI6IkR1cmF0aW9uVGltZSI7czoxOiItIjtzOjEyOiJOZXRVbml0UHJpY2UiO3M6NToiMTUsMjAiO3M6OToiTmV0QW1vdW50IjtzOjY6IjIyOCwwMCI7czoxMDoiVkFUUGVyY2VudCI7czozOiIyNSUiO3M6MzoiVkFUIjtzOjU6IjU3LDAwIjtzOjExOiJHcm9zc0Ftb3VudCI7czo2OiIyODUsMDAiO3M6ODoiSXRlbUNvZGUiO3M6NzoiU01TX09GRiI7fWk6NjthOjEwOntzOjExOiJEZXNjcmlwdGlvbiI7czoyMjoiU01TIGjDoWzDs3phdG9uIGJlbMO8bCI7czo2OiJQZXJpb2QiO3M6MTI6IjA3LjE3LTA4LjEyLiI7czo2OiJBbW91bnQiO3M6MjoiMTUiO3M6MTI6IkR1cmF0aW9uVGltZSI7czoxOiItIjtzOjEyOiJOZXRVbml0UHJpY2UiO3M6NToiMTUsMjAiO3M6OToiTmV0QW1vdW50IjtzOjY6IjE1MiwwMCI7czoxMDoiVkFUUGVyY2VudCI7czozOiIyNSUiO3M6MzoiVkFUIjtzOjU6IjM4LDAwIjtzOjExOiJHcm9zc0Ftb3VudCI7czo2OiIxOTAsMDAiO3M6ODoiSXRlbUNvZGUiO3M6NjoiU01TX09OIjt9fQ==';




            $tt = 'YTozOntzOjE2OiJTdW1tYXJ5SXRlbU5ldHRvIjtzOjg6IjMgODI3LDU4IjtzOjE0OiJTdW1tYXJ5SXRlbVZBVCI7czo2OiI5NTYsODkiO3M6MTc6IlN1bW1hcnlJdGVtQnJ1dHRvIjtzOjg6IjQgNzg0LDQ3Ijt9';




            $a = unserialize(base64_decode($aa));
            $t = unserialize(base64_decode($tt));


            function calculate_call_fees($a,$t){

                $or_item = 0;

                foreach($a as $k => $r) {
                    $or_item += fix_num($r['GrossAmount']); 
                }        

                $br =  fix_num($t['SummaryItemBrutto']);   

                if($br>$or_item){
                    $diff = $br-$or_item;
                } else {
                    $diff = 0;
                }

                echo 'First Number: ' . $br.'<br/>';
                echo 'Second Number: ' . $or_item.'<br />';
                echo 'Difference: ' . $diff.'<br />';

                echo '<hr />';
                echo '<pre>';
                print_r($a);
                echo '</pre>';
                echo '<hr />';
                echo '<pre>';
                print_r($t);
                echo '</pre>';    

            }

            function fix_num($n){
                return floatval(str_replace(Array(" ",","),array("","."),$n));
            }

            calculate_call_fees($a,$t);
最佳答案
由于浮点数的精度有限,因此将“等于”值与浮点数进行比较是很危险的-由于四舍五入的关系,您可能会产生小的差异。

相反,如果要查看两个浮点数是否“相同”,只需查看它们的差是否在某个阈值以下:

if( abs($a - $b) < 0.00000001) {
    // a and b are "equal"
}
相关推荐

php - 我应该使用/编写模板词法分析器吗

php - 关于.htaccess和友善网址的几个问题

php - 需要从php json_encode调用中输出javascript日期对象[重复]

php - 网站移至其他页面时移动

php - CodeIgniter:在WAMP上的URL中删除“ index.php”

php - regex php-在具有特定ID的div中查找内容

php - 使用PHP和AJAX执行期间杀死MySQL查询

php - PHP-回声不显示从数据库

php - 加载时间:使用PHP的DOMDocument或正则表达式解析HTML是否更快?

php - 有没有办法将浏览器重定向到本地网络上的文件?