2013-09-06 27 views
5

Tôi có một mảng kết hợp có giá trị là phao, được cho là xác suất. Như vậy, tôi tổng hợp và đòi hỏi rằng kết quả là trên thực tế 1.Bằng cách nào đó 1 không bằng 1 (PHP)

$total = array_sum($array); 
echo '$total = '.$total."\n"; 
if ($total == 1) { 
    die("total is 1"); 
} else { 
    die("total is not 1"); 
} 

này một cách bí ẩn kết quả đầu ra:

$total = 1 
total is not 1 

Làm một var_dump($total) sản lượng float(1), nhưng thậm chí $total == (float)1 lợi nhuận sai.

Điều gì đang xảy ra?

+2

http://stackoverflow.com/questions/4682889/is-floating-point-ever-ok – thumbmunkeys

Trả lời

2

Floats trong php (và các ngôn ngữ khác) là không chính xác, do đó (float)1 thực sự có thể 1.0000000000000 hay .99999999999999823477

Xem trả lời PHP - Floating Number Precision để biết thêm thông tin

+0

có cách nào để php có thể cho tôi biết giá trị thực của nó là gì? – Mala

+0

'print (number_format ($ myNumber, 32);' sẽ cho bạn thấy mức độ chính xác nào đó, nhưng theo như tôi biết, bạn không thể thấy giá trị _exact_. – Jordan

+0

whargbl "0.99999999999999988897769753748435" - tôi không có ý tưởng var_dump sẽ tròn như thế – Mala

1

Cast để int làm

if ((int)$total == 1) 

Và nó sẽ hoạt động :)

EDIT: hoặc thậm chí tốt hơn

$total = (int)array_sum($array); 
+1

điều này sẽ không may là vô ích với những gì tôi đang cố gắng làm (xem phần trên cùng của câu hỏi). Nếu các giá trị của tôi bị hỏng - mã này là gì để kiểm tra - và tổng số là trên thực tế 1.3 nó sẽ vượt qua bài kiểm tra – Mala

+0

Tôi thấy, xin lỗi vì tôi đã hiểu sai câu hỏi của bạn: ( – Quillion

3

Floating giá trị điểm là do bản chất không chính xác và rất hiếm khi bằng nhau do cách chúng được lưu trữ và các lỗi làm tròn. Bạn nên so sánh phao bằng cách xem liệu hai giá trị có "đủ gần" hay không. Tức là, so sánh giá trị tuyệt đối của sự khác biệt giữa hai giá trị với sai số nhỏ đáng kể của lỗi (thường được gọi là "epsilon").

Một ví dụ thực hiện có thể là:

if (abs($total - 1) < 0.000000001) 
    die("total is 1"); 
} else { 
    die("total is not 1"); 
} 

Lưu ý rằng các yêu cầu duy nhất của ứng dụng của bạn thực sự có thể xác định những gì một biên độ an toàn của lỗi là gì và những gì số điểm cần được làm tròn để trưng bày.


Nếu bạn đang xử lý các giá trị tiền tệ, ví dụ và yêu cầu độ chính xác chính xác, giải pháp tốt hơn là loại bỏ toàn bộ số học dấu phẩy động. Một lựa chọn trong trường hợp này sẽ là sử dụng một loại số nguyên và lưu trữ số là xu, chỉ chia ở phút cuối để hiển thị số cho người dùng (hoặc thậm chí không phân chia và chèn một dấu thập phân vào chuỗi thay thế).

Các vấn đề liên quan