Score:0

การหารจำนวนมากใน bash ส่งคืนผลลัพธ์ที่ไม่ถูกต้อง

ธง in

ฉันกำลังพยายามแปลงไบต์จำนวนมากเป็นกิกะไบต์

เสียงสะท้อน $(( 41003021288998461440 / 1073741824 ))

สิ่งนี้ส่งคืน 3827300985 ซึ่งไม่ถูกต้อง คำตอบที่ถูกต้องคือ 38187039354 11 หลักกับ 10

การใช้ 'สเกล = 30' ที่แตกต่างกันหรือการไพพ์ผ่าน bc จะไม่เปลี่ยนคำตอบ ผมทำอะไรผิดหรือเปล่า?

ฉันลองสิ่งนี้แทน:

awk -v var1=41003021288998461440 -v var2=1073741824 'BEGIN { พิมพ์ ( var1 / var2 ) }' OFMT='%25g'

ซึ่งส่งคืน "3.8187e+10" ซึ่งดูเหมือนว่าจะเป็นตัวเลขที่ถูกต้อง แต่ฉันก็คิดไม่ออกว่าจะไม่ให้อยู่ในสัญกรณ์วิทยาศาสตร์ได้อย่างไร Printf "%12d" ไม่ได้ช่วยเพราะดูเหมือนจะไม่สามารถจัดการการแบ่งในพารามิเตอร์ที่ส่งผ่านได้

ฉันสงสัยว่าการแก้ไขปัญหาสัญกรณ์วิทยาศาสตร์ awk น่าจะง่ายกว่า แต่ฉันก็ยังต้องการทราบว่าเหตุใดการหารแบบยาวด้วย echo จึงส่งกลับผลลัพธ์ที่ผิดทั้งหมด เป็นเรื่องที่น่ากังวลมาก และเนื่องจากฉันคำนวณด้วยวิธีนั้นบ่อยๆ ฉันจึงอยากทราบว่าต้องทำอย่างไรเพื่อให้เสียงสะท้อนคำนวณได้อย่างถูกต้อง

ฉันรู้ด้วยว่าฉันเคยแก้ปัญหานี้ไปแล้วครั้งหนึ่ง... แต่ฉันทำพลาดไปแล้วและตอนนี้จำไม่ได้แล้ว เฮ้อ

muru avatar
us flag
ในเวอร์ชัน awk `printf "%12f", ( var1 / var2 )` ให้ `38187039353.883324` และ `%12d` ให้ `38187039353`
hr flag
ฉันคิดว่าการกำหนด awk `OFMT` ของคุณล้มเหลวเพราะ (อย่างน้อยใน GNU awk) จะมีผลหลังจากดำเนินการบล็อก `BEGIN` เท่านั้น: ใช้ `-v OFMT='%d'` หรือเพิ่มเข้าไปในบล็อก `BEGIN { OFMT="%d"; พิมพ์ ( var1 / var2 )}`. ดู[การกำหนดตัวแปรบนบรรทัดคำสั่ง](https://www.gnu.org/software/gawk/manual/gawk.html#Assignment-Options)
hr flag
... ใน GAWK เวอร์ชันเก่า คุณอาจต้องเปิดใช้งานการสนับสนุนความแม่นยำตามอำเภอใจอย่างชัดเจนโดยใช้ตัวเลือก `-M` หรือ `--bignum`
Score:1
ธง us

ทุบตีจำนวนเต็ม ไม่ใช่ความแม่นยำโดยพลการ:

การประเมินเสร็จสิ้นในจำนวนเต็มความกว้างคงที่โดยไม่มีการตรวจสอบโอเวอร์โฟลว์ แม้ว่าการหารด้วย 0 จะถูกดักจับและตั้งค่าสถานะเป็นข้อผิดพลาด

ขีดจำกัดบนที่เป็นไปได้ในระบบสมัยใหม่คือ 2^63 สำหรับจำนวนเต็มที่มีเครื่องหมาย:

$ เสียงสะท้อน $(( 2**63 - 1 ))
9223372036854775807
$ เสียงสะท้อน $(( 2**63 ))
-9223372036854775808
$ เสียงสะท้อน $(( 2**62 ))
4611686018427387904 

หมายเลขของคุณใหญ่เกินไป (~4x) สำหรับสิ่งนั้น หากคุณต้องการคำนวณเลขคณิตความแม่นยำโดยพลการแบบสุ่มแบบโต้ตอบ ให้ใช้ Python:

>>> 41003021288998461440 / 1073741824
38187039353.88332
Score:0
ธง in

ในที่สุดก็สร้างใหม่ว่าจะทำอย่างไรให้คำนวณได้อย่างถูกต้อง และใช่ มันเกี่ยวข้องกับการใช้ 'สเกล'

BYTECOUNT=$(echo "scale=0; (( $BYTECOUNT / 1073741824 )) " | bc )

การทำงานข้างต้น (โดยก่อนหน้านี้ BYTECOUNT ตั้งค่าเป็นจำนวนเริ่มต้นที่มากอย่างไม่ลดละ) น่าแปลกที่จำเป็นต้องใช้ scale=0 เนื่องจากฉันเชื่อว่าควรเป็นค่าเริ่มต้น แต่ดูเหมือนว่าจำเป็นต้องทำให้ชัดเจนเพื่อให้การคำนวณออกมาถูกต้อง

Score:0
ธง bd

ฉันคิดว่ามันดีที่สุดที่จะใช้ dc สำหรับสิ่งนี้:

V=$(เสียงสะท้อน "8 k 41003021288998461440 1073741824 / p" | dc)
เสียงสะท้อน $V

ตั้งค่าความแม่นยำเป็น 8 หารค่าสองค่าถัดไป แล้วดึงค่านั้นออกจากสแต็ก

โพสต์คำตอบ

คนส่วนใหญ่ไม่เข้าใจว่าการถามคำถามมากมายจะปลดล็อกการเรียนรู้และปรับปรุงความสัมพันธ์ระหว่างบุคคล ตัวอย่างเช่น ในการศึกษาของ Alison แม้ว่าผู้คนจะจำได้อย่างแม่นยำว่ามีคำถามกี่ข้อที่ถูกถามในการสนทนา แต่พวกเขาไม่เข้าใจความเชื่อมโยงระหว่างคำถามและความชอบ จากการศึกษาทั้ง 4 เรื่องที่ผู้เข้าร่วมมีส่วนร่วมในการสนทนาด้วยตนเองหรืออ่านบันทึกการสนทนาของผู้อื่น ผู้คนมักไม่ตระหนักว่าการถามคำถามจะมีอิทธิพลหรือมีอิทธิพลต่อระดับมิตรภาพระหว่างผู้สนทนา