2016-03-02 11 views
8

Xin lỗi vì tiêu đề xấu, nhưng tôi không biết cách gọi nó.Tại sao php nghĩ rằng ints lớn là nổi (nhưng đôi khi chỉ)?

echo rand(0,10e20) . "\n"; // bad 
echo rand(0,10e19) . "\n"; // bad 
echo rand(0,10e18) . "\n"; // bad 
echo rand(0,10e17) . "\n"; // OK 
echo rand(0,10e16) . "\n"; 
echo rand(0,10e15) . "\n\n"; 

var_dump(10e20); // float 
var_dump(10e15); // float 

Output:

Cảnh báo: rand() dự kiến ​​tham số 2 là số nguyên, float cho trong /srv/webroot-sandbox/index.php(73): eval() 'd mã trên dòng 1

Cảnh báo: rand() dự kiến ​​tham số 2 là số nguyên, float cho trong /srv/webroot-sandbox/index.php(73): eval() 'd code on line 2

Cảnh báo: rand() hy vọng tham số 2 được số nguyên, float cho trong /srv/webroot-sandbox/index.php(73): eval() 'd code on line 3

578009006101638016 
69608699344098568 
7596902768127620 

float(1.0E+21) 
float(1.0E+16) 

Ai đó có thể giải thích những gì đang xảy ra? Đây là PHP 7, nó làm việc tốt trong PHP 5 (tốt, ít nhất là tôi đã không nhận được bất kỳ cảnh báo nào).

+2

Vẫn đang tìm kiếm nhưng MIGHT có thể vượt quá kích thước của ... – FirstOne

+0

hmm có thể cố gắng truyền và không hoạt động ở độ lớn nhất định?Nhưng buồn cười rằng nó làm việc OK trong PHP 5 – MightyPork

+0

theo hướng dẫn: http://php.net/manual/en/language.types.integer.php Một khi bạn đi ra ngoài giới hạn, bạn nhận được trong lỗi. Và điều này là cụ thể cho php7. – durbnpoisn

Trả lời

11

ints PHP được ký giá trị 64bit (trừ khi bạn đang ở trên một 32bit cài đặt), do đó họ đi (khoảng)

-9,223,372,036,854,775,808 -> +9,223,372,036,854,775,808 

Trong ký hiệu khoa học, -9.2e18 -> + 9.2e18

Vì vậy, các giá trị "xấu" của bạn chỉ đơn giản là các số nguyên quá lớn để lưu trữ dưới dạng số nguyên và PHP đang chuyển thành float để thử và bảo toàn càng nhiều giá trị càng tốt.

Và vì bạn có 10e18, đó thực sự là 1e19 và bên ngoài phạm vi max_int.

+0

Sẽ là thú vị để so sánh này với hành vi của PHP 5, đáng tiếc tôi đã nâng cấp ... – MightyPork

+1

@MightyPork, hành vi là như nhau với bất kỳ hệ thống, 32-bit số nguyên tối đa là 2^32/2-1 và số nguyên tối đa 64 bit là 2^64/2-1. (Unsigned sẽ là 2^32-1, 2^64-1 nhưng PHP không cho phép các số nguyên không dấu nếu IIRC) – Devon

+1

5.5.9 kết hợp của tôi ở trên. Nhưng lưu ý rằng trong Windows, php5 xử lý tất cả các int là 32 bit, bất kể nền tảng cơ bản là gì. ví dụ. phpwin 64bit vẫn đang sử dụng int 32 bit. –

6

Câu hỏi của bạn có thể được nền tảng phụ thuộc như phạm vi số nguyên của một:

  • 32 chút nền tảng là -2,147,483,648-2,147,483,647
  • 64 nền tảng bit được -9,223,372,036,854,775,808 để 9,223,372,036,854,775,808

Đối với tôi, chạy một hệ thống 64 bit nó mang lại kết quả như sau.

var_dump(10e20 > PHP_INT_MAX); // true 
var_dump(10e19 > PHP_INT_MAX); // true 
var_dump(10e18 > PHP_INT_MAX); // true 
var_dump(10e17 > PHP_INT_MAX); // false 
var_dump(10e16 > PHP_INT_MAX); // false 
var_dump(10e15 > PHP_INT_MAX); // false 

Kết quả này tương quan trực tiếp với kết quả của bạn và có thể giải thích một fiddle hoặc máy chủ web của bạn hiển thị các kết quả khác nhau.

Lý do nó hành xử khác nhau trên PHP 7 được giải thích here:

Trước đây, chức năng nội bộ sẽ âm thầm cắt xén số sản xuất từ ​​coercions float-to-số nguyên khi phao quá lớn đại diện như một số nguyên. Bây giờ, một E_WARNING sẽ được phát ra và NULL sẽ được trả lại.

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