Puncte:0

Divizarea numerelor mari în bash returnează un rezultat greșit

drapel in

Încerc să convertesc un număr foarte mare de octeți în gigaocteți.

echo $(( 41003021288998461440 / 1073741824 ))

Aceasta returnează 3827300985. Este incorect. Răspunsul corect ar fi 38187039354. 11 cifre față de 10.

Utilizarea „scale = 30” diferită sau trecerea prin bc nu schimbă răspunsul. ce fac greșit?

Ca alternativă am încercat asta:

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

Care returnează „3.8187e+10”, care pare a fi corect numeric, dar apoi nu îmi pot da seama cum să nu intru în notația științifică. Printf „%12d” nu ajută, deoarece nu poate gestiona diviziunea într-un parametru transmis.

Bănuiesc că rezolvarea problemei de notație științifică awk ar fi probabil mai ușoară, dar aș dori totuși să știu de ce împărțirea lungă cu ecou doar returnează un rezultat complet greșit. Este foarte îngrijorător și, din moment ce fac calcule în acest fel frecvent, aș dori să știu ce trebuie să fac pentru ca ecou să calculeze cu precizie.

Știu și că am rezolvat problema o dată înainte... dar am pierdut cum am făcut-o și nu-mi mai amintesc acum, suspin.

muru avatar
drapel us
În versiunea awk, `printf "%12f", ( var1 / var2 )` îmi dă `38187039353.883324`, iar `%12d` dă `38187039353`
drapel hr
Cred că atribuirea ta awk `OFMT` eșuează pentru că (cel puțin în GNU awk) are efect numai după ce blocul `BEGIN` este executat: fie folosește `-v OFMT='%d'`, fie adaugă-l în blocul `BEGIN` { OFMT="%d"; print ( var1 / var2 )}`. Consultați [Atribuirea variabilelor pe linia de comandă](https://www.gnu.org/software/gawk/manual/gawk.html#Assignment-Options).
drapel hr
... în versiunile mai vechi de GAWK, poate fi necesar să activați suportul de precizie arbitrară în mod explicit, folosind opțiunile `-M` sau `--bignum`
Puncte:1
drapel us

Bash numere întregi nu sunt de precizie arbitrară:

Evaluarea se face în numere întregi cu lățime fixă, fără verificarea depășirii, deși împărțirea cu 0 este prinsă și marcată ca o eroare.

O limită superioară probabilă în sistemele moderne ar fi 2^63 pentru numere întregi cu semn:

$ echo $(( 2**63 - 1 ))
9223372036854775807
$ echo $(( 2**63 ))
-9223372036854775808
$ echo $(( 2**62 ))
4611686018427387904 

Numărul dvs. este prea mare (~4x) pentru asta. Dacă doriți să faceți aritmetică de precizie arbitrară aleatorie în mod interactiv, utilizați Python:

>>> 41003021288998461440 / 1073741824
38187039353.88332
Puncte:0
drapel bd

Mi se pare cel mai bine să folosesc dc pentru asta:

V=$(echo „8 k 41003021288998461440 1073741824 / p” | dc)
eco $V

Aceasta setează precizia la 8, împarte următoarele două valori și apoi o scoate din stivă.

Puncte:0
drapel in

În cele din urmă, a reconstruit cum se face să calculeze cu precizie. Și da, a implicat folosirea „scalei”.

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

Cele de mai sus au funcționat (cu BYTECOUNT setat anterior la numărul inițial extrem de mare). Ciudat că scara = 0 este necesară, deoarece cred că aceasta ar trebui să fie implicită, dar pare a fi necesar să o facem explicită pentru ca calculul să iasă corect.

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.