2012-03-08 27 views
9

Có một số hành vi kỳ lạ Tôi đã tự hỏi nếu có ai đó có thể dọn dẹp cho tôi.Phủ định của Hex trong PHP, hành vi vui nhộn

Check it out

$hex = 0x80008000; 

print_r(decbin(intval($hex)) . '<br/>'); 
print_r(decbin($hex)); 

Đầu ra

10000000000000001000000000000000 
10000000000000001000000000000000 

Đúng như dự đoán.

Nhưng

$hex = 0x80008000; 

print_r(decbin(~intval($hex)) . '<br/>'); 
print_r(decbin(~$hex)); 

Đầu ra

1111111111111110111111111111111 
1111111111111111111111111111111 

Tại sao các bit giữa không chuyển đổi khi $hex là phủ nhận?

+0

Bạn đang sử dụng phiên bản PHP nào? Trường hợp thứ hai hoạt động với tôi trên 5.3.6 –

+0

Tôi đang chạy 5.3.8 và sự cố tồn tại. – Pateman

+0

Tôi đang sử dụng 5.2.17 – Vigrond

Trả lời

0

Gonna đưa ra câu hỏi của riêng tôi tại đây.

Có sự khác biệt 32 bit/64 bit.

Trong các hệ thống 32 bit, loại phao phải chiếm hai không gian bộ nhớ để nhận 64 bit bắt buộc. Php sử dụng độ chính xác gấp đôi (xem http://en.wikipedia.org/wiki/Floating_point#IEEE_754:_floating_point_in_modern_computers)

Giá trị $ hex được đánh giá là loại phao. Hàm intval và decbin chuyển đổi kiểu này thành kiểu int (ví dụ 1 ở trên)

Trong ví dụ thứ hai, chúng ta đang sử dụng toán tử bitwise TRƯỚC KHI chúng ta sử dụng decbin. Điều này lật các bit trong phao chính xác không gian hai bộ nhớ chính xác đầu tiên, và sau đó được chuyển thành int thứ hai.Cung cấp cho chúng tôi một cái gì đó khác với những gì chúng tôi mong đợi.

Thật vậy, nếu chúng ta đặt phủ nhận bên trong của intval() như sau:

$hex = 0x80008000; 

print_r(decbin(intval(~$hex)) . '<br/>'); 
print_r(decbin(~$hex)); 

Chúng tôi nhận được

1111111111111111111111111111111 
1111111111111111111111111111111 

Như đầu ra.

Tôi không đủ tốt để chứng minh điều này bằng toán học (có thể được tìm ra với sự trợ giúp của bài viết này http://en.wikipedia.org/wiki/Double_precision). Nhưng có lẽ khi tôi có thời gian sau -_-

Tôi nghĩ rằng việc tìm hiểu cách số được biểu diễn trong máy tính là rất quan trọng để chúng tôi có thể hiểu được những bất thường như thế này và không gọi chúng là lỗi.

-1

Có thể là một trường hợp thuộc này:

Từ các nhà khai thác php Bitwise trang http://us3.php.net/manual/en/language.operators.bitwise.php

NGƯỜI ĐÀN ÔNG KHÔNG hoặc bổ sung cho nhà điều hành (~) và số nhị phân tiêu cực có thể thể gây nhầm lẫn.

~ 2 = -3 vì bạn sử dụng công thức ~ x = -x - 1 Bitwise bổ sung một số thập phân là sự phủ định của số trừ đi 1.

Chú ý: chỉ sử dụng 4 bit vào đây để các ví dụ dưới đây nhưng trên thực tế, PHP sử dụng 32 bit.

Chuyển đổi số thập phân âm (tức là: -3) thành nhị phân mất 3 bước: 1) chuyển đổi phiên bản dương của số thập phân thành nhị phân (ví dụ: 3 = 0011) 2) lật bit (ví dụ: 0011 trở thành 1100) 3) thêm 1 (ví dụ: 1100 + 0001 = 1101)

Bạn có thể tự hỏi làm thế nào để 1101 = -3. Vâng PHP sử dụng phương pháp "bổ sung 2" để hiển thị số nhị phân âm. Nếu bên trái nhất bit là 1 thì số nhị phân là số âm và bạn lật các bit và thêm 1. Nếu đó là 0 thì nó là số dương và bạn không phải làm bất kỳ thứ gì. Vì vậy, 0010 sẽ là một tích cực 2. Nếu nó là 1101, nó là tiêu cực và bạn lật các bit để có được 0010. Thêm 1 và bạn nhận được 0011 bằng -3.

+0

Tôi không nghĩ rằng đó là liên quan đến câu hỏi. Từ sự hiểu biết của tôi, 'intval ($ hex)' phải chính xác tương đương với '$ hex', vì vậy tôi mong đợi' ~ intval ($ hex) === ~ $ hex'. –

+0

Vâng tôi không chuyển đổi bất cứ điều gì ở đây, chỉ cần đại diện cho số ở định dạng nhị phân. – Vigrond

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