Điểm:0

Phép chia số lớn trong bash trả về kết quả sai

lá cờ in

Tôi đang cố chuyển đổi một số lượng rất lớn byte thành gigabyte.

tiếng vang $(( 41003021288998461440 / 1073741824 ))

Điều này trả về 3827300985. Điều đó không chính xác. Câu trả lời đúng sẽ là 38187039354. 11 chữ số so với 10.

Sử dụng 'tỷ lệ = 30' khác hoặc chuyển qua bc không thay đổi câu trả lời. Tôi đang làm gì sai?

Để thay thế, tôi đã thử điều này:

awk -v var1=41003021288998461440 -v var2=1073741824 'BEGIN { print ( var1 / var2 ) }' OFMT='%25g'

Trả về "3.8187e+10", có vẻ đúng về mặt số học, nhưng sau đó tôi không thể tìm ra cách để không nhận được ký hiệu khoa học. Printf "%12d" không hữu ích vì dường như nó không thể xử lý phép chia trong tham số đã truyền.

Tôi nghi ngờ việc khắc phục sự cố ký hiệu khoa học awk có thể sẽ dễ dàng hơn, nhưng tôi vẫn muốn biết tại sao phép chia dài với echo chỉ trả về một kết quả hoàn toàn sai. Điều đó rất đáng lo ngại và vì tôi thường xuyên thực hiện các phép tính theo cách đó, nên tôi muốn biết mình cần làm gì để tiếng vang tính toán chính xác.

Tôi cũng biết rằng tôi đã từng khắc phục sự cố một lần trước đây... nhưng tôi đã làm mất cách thực hiện và giờ không thể nhớ lại, thở dài.

muru avatar
lá cờ us
Trong phiên bản awk, `printf "%12f", ( var1 / var2 )` cho tôi `38187039353.883324` và `%12d` cho tôi `38187039353`
lá cờ hr
Tôi nghĩ rằng phép gán awk `OFMT` của bạn không thành công vì (ít nhất là trong GNU awk) nó chỉ có hiệu lực sau khi khối `BEGIN` được thực thi: hoặc sử dụng `-v OFMT='%d'` hoặc thêm nó vào bên trong khối `BEGIN { OFMT="%d"; in ( var1 / var2 )}`. Xem [Gán biến trên dòng lệnh](https://www.gnu.org/software/gawk/manual/gawk.html#Assignment-Options).
lá cờ hr
... trong các phiên bản GAWK cũ hơn, bạn cũng có thể cần bật hỗ trợ chính xác tùy ý một cách rõ ràng bằng cách sử dụng các tùy chọn `-M` hoặc `--bignum`
Điểm:1
lá cờ us

Bash số nguyên không phải là độ chính xác tùy ý:

Đánh giá được thực hiện trong các số nguyên có độ rộng cố định mà không kiểm tra tràn, mặc dù phép chia cho 0 bị mắc kẹt và bị gắn cờ là lỗi.

Giới hạn trên có khả năng xảy ra trong các hệ thống hiện đại sẽ là 2^63 đối với các số nguyên đã ký:

$ tiếng vang $(( 2**63 - 1 ))
9223372036854775807
$ tiếng vang $(( 2**63 ))
-9223372036854775808
$ tiếng vang $(( 2**62 ))
4611686018427387904 

Số của bạn waaaay quá lớn (~4x) cho điều đó. Nếu bạn muốn thực hiện tương tác số học chính xác tùy ý ngẫu nhiên, hãy sử dụng Python:

>>> 41003021288998461440 / 1073741824
38187039353.88332
Điểm:0
lá cờ in

Cuối cùng xây dựng lại làm thế nào để làm cho nó tính toán chính xác. Và vâng, nó liên quan đến việc sử dụng 'tỷ lệ'.

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

Cách trên đã hoạt động (với BYTECOUNT trước đó được đặt thành số ban đầu cực lớn). Điều kỳ lạ là scale=0 là cần thiết vì tôi tin rằng đó được coi là mặc định, nhưng có vẻ như cần phải làm cho nó rõ ràng để có được phép tính chính xác.

Điểm:0
lá cờ bd

Tôi thấy tốt nhất là sử dụng dc cho việc này:

V=$(echo "8 k 41003021288998461440 1073741824 / p" | dc)
tiếng vang $V

Điều này đặt độ chính xác thành 8, chia hai giá trị tiếp theo và sau đó bật nó ra khỏi ngăn xếp.

Đăng câu trả lời

Hầu hết mọi người không hiểu rằng việc đặt nhiều câu hỏi sẽ mở ra cơ hội học hỏi và cải thiện mối quan hệ giữa các cá nhân. Ví dụ, trong các nghiên cứu của Alison, mặc dù mọi người có thể nhớ chính xác có bao nhiêu câu hỏi đã được đặt ra trong các cuộc trò chuyện của họ, nhưng họ không trực giác nhận ra mối liên hệ giữa câu hỏi và sự yêu thích. Qua bốn nghiên cứu, trong đó những người tham gia tự tham gia vào các cuộc trò chuyện hoặc đọc bản ghi lại các cuộc trò chuyện của người khác, mọi người có xu hướng không nhận ra rằng việc đặt câu hỏi sẽ ảnh hưởng—hoặc đã ảnh hưởng—mức độ thân thiện giữa những người đối thoại.