PHP so sánh float

So sánh hai bit dữ liệu trong PHP khá đơn giản nhưng có những trường hợp đặc biệt khi so sánh dữ liệu đơn giản cần hơi khác một chút. Một trong những vấn đề phổ biến là so sánh các số float, một lỗi phổ biến là so sánh hai số float giống như cách bạn so sánh hai số nguyên hoặc hai chuỗi

Số float, double hoặc số thực trông như thế nào?
1. 234
1. 2e4
7E-10

Điều này là do cách PHP lưu trữ các số float (còn được gọi là số kép hoặc số thực) mang lại cho loại dữ liệu này độ chính xác rất hạn chế dẫn đến các số hơi sai lệch, để có giải thích sâu hơn, vui lòng đọc bài viết sau http. //php. net/manual/vi/ngôn ngữ. các loại. trôi nổi. php

Sự cố này chỉ xảy ra sau khi phép tính được thực hiện trên số thực

Cách tốt nhất để so sánh hai số float để có được phép so sánh chính xác là chuyển đổi giá trị thành một loại dữ liệu thay thế, chẳng hạn như số nguyên, chuỗi hoặc sử dụng “bccomp” cho phép bạn so sánh 2 loại dữ liệu float với nhau theo độ chính xác mà bạn chỉ định (

equalSo sánh hai số float đã cho và trả về một giá trị boolean mô tả xem chúng có bằng nhau không. greaterThanSo sánh hai số float đã cho và trả về một giá trị boolean mô tả nếu số float đầu tiên lớn hơn số float thứ hai. greaterThanOrEqualSo sánh hai số float đã cho và trả về một giá trị boolean mô tả nếu số float đầu tiên lớn hơn hoặc bằng số float thứ hai

So sánh số dấu phẩy động

 
if(abs($price_1 - $price_2) < 0.00001) {
    print '$price_1 and $price_2 are equal.';
} else {
    print '$price_1 and $price_2 are not equal.';
}
?>
  
  

Ví dụ liên quan trong cùng thể loại


Để so sánh các giá trị float trong PHP, mã như sau -

Thí dụ

Bản thử trực tiếp

$b";
   if($a == $b) {
      echo "
Both the values are equal!";    } else {       echo "
Both the values aren\'t equal";    } ?>

đầu ra

Điều này sẽ tạo ra đầu ra sau−

2.5
3.5
Both the values aren\'t equal

Thí dụ

Bây giờ chúng ta hãy xem một ví dụ khác -

Bản thử trực tiếp

$b";
   if((round($a, 2)) == (round($b, 2))) {
      echo "
Both the values are equal!";    } else {       echo "
Both the values aren\'t equal";    } ?>

đầu ra

Điều này sẽ tạo ra ví dụ sau−

1.967
1.969
Both the values are equal!

PHP so sánh float


PHP so sánh float

In the gettype() manual, it says "(for historical reasons "double" is returned in case of a float, and not simply "float") ".

However, I think that internally PHP sometimes uses the C double definition (i.e. a double is twice the size of a float/real). See the example below:

//Function required to reverse a string on blocks of two
function strrev_x($s, $x = 2) {
    if ($x <= 1) {
        return strrev($s);
    } else {
        return (implode(array_reverse(array_map('implode', array_chunk(str_split($s), $x)))));
    }
}

echo 'double pack'. PHP_EOL;
$tst = pack('d', '1.6');
var_dump(strrev_x(bin2hex($tst)));
$tst = pack('d', 8-6.4);
var_dump(strrev_x(bin2hex($tst)));
echo 'float pack'. PHP_EOL;
$tst = pack('f', '1.6');
var_dump(strrev_x(bin2hex($tst)));
$tst = pack('f', 8-6.4);
var_dump(strrev_x(bin2hex($tst)));
?>
(The strrev_x-bin2hex combination is just to give printable characters.)

Given that PHP treats doubles and floats identically, I'd expected the same string as output, however, the output is:

double pack
string(16) "3ff999999999999a" //Here you see that there is a minute difference...
string(16) "3ff9999999999998"
float pack
string(8) "3fcccccd" //.. which doesn't exist here
string(8) "3fcccccd"

So, as an alternative to using
  $float1 === $float2
one could use
  pack('f', $float1) === pack ('f', $float2)
with a big footnote that one should really remember that one is *reducing* your accuracy of the comparison. AFAIK is this the only way (apart from epsilon methods) to securely compare two floats.

Trong PHP, kích thước của một giá trị thả nổi phụ thuộc vào nền tảng. Do biểu diễn bên trong của các số dấu phẩy động, có thể có đầu ra không mong muốn trong khi thực hiện hoặc kiểm tra các giá trị dấu phẩy động cho bằng nhau. Ví dụ, xem chương trình sau

PHP




<?php

 

// Declare valuable and initialize it

$value1 = 8 - 6.4;

$value2 = 1.6;

 

// Compare the values

True
0
True
1_______51_______
True
3_______53_______
True
5

True
6_______5_______7
True
8
True
9

bool(true)
0

bool(true)
1
bool(true)
2

True
6_______5_______7
bool(true)
5
True
9

bool(true)
0

 

bool(true)
8

đầu ra.

False

 

Giải trình. Đầu ra của mã này là Sai, điều này rất khó đoán nhưng trong PHP, giá trị1 không chính xác là 1. 6 tôi. e nó đến từ sự khác biệt giữa 8 và 6. 4 mà hóa ra lại là 1. 599999 đó là lý do tại sao tuyên bố này hóa ra là sai

Làm thế nào để giải quyết vấn đề trên?
Phương pháp 1. Để kiểm tra sự bằng nhau trong các giá trị dấu phẩy động, hãy sử dụng máy epsilon hoặc chúng ta có thể gọi nó là sự khác biệt nhỏ nhất trong phép tính trong hệ thống máy tính

chương trình 1.   

PHP




<?php

<?php0

 

<?php1

<?php2

$value1 <?php4

$value2 <?php6

<?php7 <?php8

 

<?php9

True
0
True
1// Declare valuable and initialize it2_______5_______1$value1 // Declare valuable and initialize it5$value250_______7<?php7
True
5

True
6_______5_______7 $value12
True
9

bool(true)
0

bool(true)
1
bool(true)
2

True
6_______5_______7 $value19
True
9

bool(true)
0

 

bool(true)
8

đầu ra.

True

 

Giải trình. Trong mã này, sử dụng hai số dấu phẩy động value1 và value2 cùng với epsilon. Bây giờ lấy hiệu tuyệt đối của các giá trị (giá trị 1 và giá trị 2) bằng cách sử dụng hàm được xác định trước có tên là abs(). Mã này sẽ đưa ra giá trị tuyệt đối nhưng câu hỏi đặt ra là tại sao chúng ta lại lấy giá trị tuyệt đối. Bạn có thể thấy rằng cả hai giá trị có cùng chữ số sau số thập phân cho đến giá trị chính xác 7. Điều này rất khó để hệ thống phân tích so sánh.  

Làm cách nào để so sánh hai giá trị float trong PHP?

Giải thích. Trong mã này, sử dụng hai số dấu phẩy động value1 và value2 cùng với epsilon. Bây giờ lấy hiệu tuyệt đối của các giá trị (giá trị 1 và giá trị 2) bằng cách sử dụng hàm được xác định trước có tên là abs() . Mã này sẽ đưa ra giá trị tuyệt đối nhưng câu hỏi đặt ra là tại sao chúng ta lại lấy giá trị tuyệt đối.

Làm cách nào để kiểm tra xem một giá trị có nổi hay không trong PHP?

Hàm is_float() kiểm tra xem một biến có thuộc kiểu float hay không. Hàm này trả về true(1) nếu biến là kiểu float, ngược lại trả về false.

Sự khác biệt giữa float và double trong PHP là gì?

Không có sự khác biệt trong PHP . float , double hoặc real là cùng một kiểu dữ liệu. Ở cấp độ C, mọi thứ được lưu trữ dưới dạng gấp đôi. Kích thước thực vẫn phụ thuộc vào nền tảng.

Sự khác biệt giữa float và thập phân trong PHP là gì?

Float lưu trữ giá trị gần đúng và thập phân lưu trữ giá trị chính xác . Tóm lại, các giá trị chính xác như tiền nên sử dụng số thập phân và các giá trị gần đúng như phép đo khoa học nên sử dụng số float.