ค่าสูงสุดของตัวแปรเชลล์ bash ตัวเลขคืออะไร


17

ฉันอยากรู้ว่าเกิดอะไรขึ้นเมื่อตัวแปรตัวเลขใน bash เพิ่มขึ้นโดยไม่หยุดมัน จำนวนสามารถรับได้เท่าใด มันจะล้นและกลายเป็นลบและจะเพิ่มขึ้นเรื่อย ๆ ตลอดไปหรือไม่ มันจะแตกและลื่นไถลไปที่จุดหยุดในบางจุดหรือไม่?

ฉันใช้หน่วยประมวลผล AMD x86_64 แต่ฉันยินดีที่จะรับฟังคำตอบ 32 บิตเช่นกันเพียงระบุว่าคุณกำลังพูดถึงเรื่องอะไร ฉันกำลังใช้งาน Fedora21 64 บิต

ฉันไปไกลและกว้าง แต่ก็ไม่พบชิ้นอาหารอันโอชะนี้ด้วยเหตุผลแปลก ๆ ดูเหมือนว่ามันจะเป็นข้อมูลพื้นฐานในคู่มือและเช่นนั้น


3
วิธีการพิมพ์พลังบางส่วนของ 2 เป็นตัวเริ่มต้น:for i in {0..70}; do echo 2 to the power of $i = $((2**i)); done
mpy

1
หากคุณต้องการตัวเลขจำนวนมากคุณอาจเปลี่ยนไปkshใช้เลขคณิตเลขทศนิยมซึ่งไม่ใช่จำนวนเต็มเช่นbash: ksh -c 'echo $((2**1023))'8.98846567431157954e+307
jlliagre

ฉันจะจำ ksh ถ้าฉันต้องการจุดลอยตัวหรือค่าในสตราโตสเฟียร์จุดลอยตัวนั้นมีประโยชน์มาก แต่คำถามนี้เป็นเพียงเพื่อให้ฉันรู้ว่าขีด จำกัด ของระบบไม่ใช่เพราะฉันต้องการเกินขีด จำกัด ฉันจะทำอะไรบางอย่างที่ mpy แนะนำฉันไม่ได้เริ่มด้วยเพราะฉันไม่ต้องการความเสี่ยงที่ทำให้ระบบล่ม
Max Power

คำตอบ:


22

มันอาจจะลงมาในเวอร์ชั่นทุบตีระบบปฏิบัติการและสถาปัตยกรรมซีพียูของคุณ ทำไมคุณไม่ลองด้วยตัวเองล่ะ ตั้งค่าตัวแปรเป็น (2 ^ 31) -1 จากนั้นเพิ่มขึ้นตั้งเป็น 2 ^ 32 จากนั้นเพิ่มขึ้นตั้งเป็น 2 ^ 64 จากนั้นเพิ่มขึ้นเป็นต้น

ที่นี่ฉันเพิ่งลองด้วยตัวเองบน Core i7 Mac ที่ใช้งาน OS X "El Capitan" v10.11.3 และดูเหมือนว่า bash กำลังใช้เลขจำนวนเต็ม 64 บิตที่ลงชื่อแล้ว

$ uname -a
ดาร์วิน Spiff.local 15.3.0 เคอร์เนลดาร์วินเวอร์ชัน 15.3.0: ธ.ค. 10 18:40:58 PST 2015; root: xnu-3248.30.4 ~ 1 / RELEASE_X86_64 x86_64
$ bash - รุ่น
ทุบตี - รุ่น
GNU bash รุ่น 3.2.57 (1) - ปล่อย (x86_64-apple-darwin15)
ลิขสิทธิ์ (C) 2007 มูลนิธิซอฟต์แวร์เสรี, Inc.
$
$ ((X = 2 ** 16)); echo $ X
65536 <- โอเคอย่างน้อย UInt16
$ ((X = 2 ** 32)); echo $ X
4294967296 <- โอเคอย่างน้อย UInt32
$ ((X = 2 ** 64)); echo $ X
0 <- oops ไม่ใช่ UInt64
$ ((X = (2 ** 63) -1)); echo $ X
9223372036854775807 <- โอเคอย่างน้อย SInt64
$ ((X ++)); echo $ X
-9223372036854775808 <- ลบมากล้นและลบ ต้องเป็น SInt64

3

ฉันตั้งวง while return status is 0 increment a variable with addition and print the variable to stdout ฉันเริ่มมันแค่ 2 ^ 31 ฉันปล่อยให้มันผ่านทั้ง 2 ^ 31 และ 2 ^ 32 โดยไม่มีปัญหาหยุดมันแล้วตั้งค่าเริ่มต้นให้ต่ำกว่า 2 ^ 63 ผลที่ได้คือว่ามันรีดอย่างราบรื่นจาก 9.22e18 ถึง -9.22e18 และเพิ่มขึ้นอย่างต่อเนื่องในเชิงบวก (ไปทางศูนย์)

เพียงเพื่อตรวจสอบว่าwhile [ $? -eq 0 ]จริง ๆ แล้วฉันใช้สถานะทางออกของคำสั่งในขณะที่ลูปไม่ใช้สถานะออกจากสคริปต์ก่อนหน้าหรือบางคี่ฉันก็วิ่งมันด้วยคำสั่งพิเศษภายในวงที่ออกแบบมาเพื่อสร้างทางออกไม่เป็นศูนย์ สถานะที่เพิ่มขึ้นโดยเฉพาะอย่างยิ่ง

ดังนั้นจึงมีการเซ็นชื่อมันจะเกลือกกลิ้งมากกว่าหยุดที่ค่าสูงสุดและจะทำเช่นนั้นโดยไม่มีข้อความแสดงข้อผิดพลาด ดังนั้นจึงเป็นไปได้ที่จะจบลงด้วยการวนซ้ำไม่สิ้นสุดอย่างแท้จริง ไม่ จำกัด ฮาร์ดแวร์ 64 บิตและ 64 บิตระบบปฏิบัติการลินุกซ์ให้เป็นมาตรฐาน 16 หรือ 32 บิตเก่า


2

bashใช้จำนวนเต็ม 64 บิต ดังนั้นหากคุณเพิ่มขึ้นหลังจากที่ตัวแปรไปถึงจำนวนสูงสุดตัวแปรจะล้น ด้านล่างคือการทดสอบของฉันด้วยจำนวนเต็ม int และลงนามไม่ได้ลงนาม

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
โปรดเพิ่มข้อความอธิบายวิธีการตอบคำถาม ดูเหมือนว่าคุณกำลังพยายามแสดงขีด จำกัด สูงสุดผ่านทางรหัส - คุณช่วยอธิบายได้ไหมว่าทำไมรหัสนี้ถึงได้ผลลัพธ์ที่ต้องการ?
Sir Adelaide
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.