Giá trị tối đa của biến bash shell số là gì?


17

Tôi tò mò không biết chuyện gì sẽ xảy ra khi một biến số trong bash được tăng lên mà không cố tình dừng nó. Số lượng có thể nhận được lớn như thế nào? Nó sẽ tràn và trở nên tiêu cực và chỉ tiếp tục gia tăng mãi mãi? Nó sẽ phá vỡ và trượt đến một điểm dừng?

Tôi đang sử dụng bộ xử lý AMD x86_64, nhưng tôi cũng rất vui khi nghe câu trả lời 32 bit, chỉ cần xác định rõ bạn đang nói về điều gì. Tôi đang chạy Fedora21 64 bit.

Tôi đã googled xa và rộng nhưng không tìm thấy miếng ngon cụ thể này vì một số lý do kỳ lạ. Có vẻ như nó sẽ là một phần thông tin cơ bản trong tất cả các hướng dẫn và như vậy.


3
Làm thế nào về việc in ra một số quyền hạn của 2 khi bắt đầu:for i in {0..70}; do echo 2 to the power of $i = $((2**i)); done
mpy

1
Nếu bạn muốn số lớn, bạn có thể chuyển sang sử dụng kshsố học dấu phẩy động, không phải số nguyên như bash: ksh -c 'echo $((2**1023))'8.98846567431157954e+307
jlliagre

Tôi sẽ ghi nhớ ksh nếu tôi cần điểm nổi hoặc giá trị trong tầng bình lưu, điểm nổi có thể khá hữu ích. Nhưng câu hỏi này chỉ đơn giản là để tôi biết giới hạn của hệ thống của mình, không phải vì tôi cần vượt quá giới hạn của nó. Tôi sẽ làm một cái gì đó như mpy gợi ý, tôi đã không bắt đầu vì tôi không muốn mạo hiểm gây ra sự cố hệ thống.
Công suất tối đa

Câu trả lời:


22

Nó có thể đi xuống phiên bản bash, HĐH và kiến ​​trúc CPU của bạn. Tại sao bạn không tự thử? Đặt một biến thành (2 ^ 31) -1, sau đó tăng nó, đặt nó thành 2 ^ 32, sau đó tăng nó, đặt nó thành 2 ^ 64, sau đó tăng nó, v.v.

Ở đây, tôi đã tự mình thử nó trên Core i7 Mac chạy OS X "El Capitan" v10.11.3 và có vẻ như bash đang sử dụng các số nguyên 64 bit đã ký.

$ uname -a
Darwin Spiff.local 15.3.0 Hạt nhân Darwin Phiên bản 15.3.0: Ngày 10 tháng 12 lúc 18 giờ 40 phút PST 2015; root: xnu-3248.30.4 ~ 1 / RELEASE_X86_64 x86_64
$ bash - chuyển đổi
bash
GNU bash, phiên bản 3.2.57 (1) -release (x86_64-apple-darwin15)
Bản quyền (C) 2007 Phần mềm miễn phí Foundation, Inc.
$
$ ((X = 2 ** 16)); tiếng vang $ X
65536 <- được, ít nhất UInt16
$ ((X = 2 ** 32)); tiếng vang $ X
4294967296 <- được, ít nhất UInt32
$ ((X = 2 ** 64)); tiếng vang $ X
0 <- ôi, không phải UInt64
$ ((X = (2 ** 63) -1)); tiếng vang $ X
9223372036854775807 <- được, ít nhất SInt64
$ ((X ++)); tiếng vang $ X
-9223372036854775808 <- tràn và bọc âm. Phải là SInt64

3

Tôi thiết lập một vòng lặp. while return status is 0 increment a variable with addition and print the variable to stdout Tôi đã bắt đầu nó chỉ dưới 2 ^ 31, tôi để nó vượt qua cả 2 ^ 31 và 2 ^ 32 mà không có vấn đề gì, dừng lại, sau đó đặt giá trị ban đầu chỉ dưới 2 ^ 63. Kết quả là nó liên tục cuộn từ 9,22e18 đến -9,22e18 và tiếp tục tăng tích cực. (về không)

Chỉ để kiểm tra xem tôi while [ $? -eq 0 ]có thực sự sử dụng trạng thái thoát của các lệnh trong vòng lặp while không, không sử dụng trạng thái thoát của tập lệnh trước hoặc một số lẻ, tôi cũng chạy nó với một lệnh bổ sung bên trong vòng lặp được thiết kế để tạo ra một lối thoát khác không tình trạng ở mức tăng cụ thể.

Vì vậy, nó đã được ký, nó sẽ cuộn qua thay vì dừng ở giá trị tối đa, và nó làm như vậy mà không có bất kỳ thông báo lỗi. Vì vậy, nó có thể kết thúc trong một vòng lặp thực sự vô hạn. Nó không giới hạn phần cứng 64 bit và HĐH linux 64 bit theo tiêu chuẩn 16 hoặc 32 bit cũ.


2

bash sử dụng số nguyên 64 bit. Vì vậy, nếu bạn tăng sau khi biến đạt đến số tối đa, biến sẽ tràn. Dưới đây là thử nghiệm của tôi với số nguyên không dấu và số nguyên đã ký.

MAX_UINT = 18446744073709551615
MAX_INT = 9223372036854775807

$ printf "%llu\n" $((2**64))
0
$ printf "%llu\n" $((2**64-1))
18446744073709551615

$ printf "%lld\n" $((2**63-1))
9223372036854775807
$ printf "%lld\n" $((2**63))
-9223372036854775808
$ printf "%lld\n" $((2**64-1))
-1

2
vui lòng thêm một số văn bản giải thích làm thế nào điều này trả lời câu hỏi. Có vẻ như bạn đang cố gắng chứng minh các giới hạn trên thông qua mã - bạn có thể giải thích tại sao mã này sẽ đạt được kết quả cần thiết không?
Ngài Adelaide
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.