Giả sử rằng hai số được lưu trữ trong hai tệp khác nhau a.txtvà b.txt.
Mỗi số đủ lớn (hơn 30 chữ số) để không được hỗ trợ bởi loại dữ liệu số được sử dụng bởi bash.
Làm thế nào tôi có thể thêm chúng trong vỏ?
pythonnhư phk đề xuất
                Giả sử rằng hai số được lưu trữ trong hai tệp khác nhau a.txtvà b.txt.
Mỗi số đủ lớn (hơn 30 chữ số) để không được hỗ trợ bởi loại dữ liệu số được sử dụng bởi bash.
Làm thế nào tôi có thể thêm chúng trong vỏ?
pythonnhư phk đề xuất
                Câu trả lời:
Giả sử chúng là số thập phân, bạn có thể làm:
paste -d + a.txt b.txt | bcCoi chừng bcdòng đó kết thúc các số rất dài (hơn 68 hoặc 69 chữ số tùy theo việc thực hiện). Với GNU bc, bạn có thể vô hiệu hóa nó bằng cách đặt BC_LINE_LENGTHbiến môi trường thành 0, như với:
paste -d + a.txt b.txt | BC_LINE_LENGTH=0 bcBí quyết là không sử dụng bashđể thực hiện phép cộng 1 .
Đầu tiên, đọc mỗi số thành một biến riêng biệt. Điều này giả định rằng các tệp chỉ chứa một số và không có thông tin khác.
a="$(<a.txt)"
b="$(<b.txt)"Sau đó sử dụng bcmáy tính để nhận kết quả:
bc <<<"$a + $b"bc là một "ngôn ngữ và máy tính số học chính xác tùy ý".
Để lưu trữ kết quả trong một biến c:
c="$( bc <<<"$a + $b" )"Nếu <<<cú pháp cảm thấy kỳ lạ (nó được gọi là "chuỗi ở đây" và là một phần mở rộng cho cú pháp shell POSIX được hỗ trợ bởi bashvà một vài shell khác), thay vào đó bạn có thể sử dụng printfđể gửi bổ sung tới bc:
printf '%s + %s\n' "$a" "$b" | bcVà lưu trữ kết quả trong cmột lần nữa:
c="$( printf '%s + %s\n' "$a" "$b" | bc )"1  Sử dụng bashđể thực hiện việc cộng hai số cực lớn sẽ đòi hỏi phải thực hiện, trong bashkịch bản, một thói quen để thực hiện số học chính xác tùy ý . Điều này là hoàn toàn có thể thực hiện được, nhưng cồng kềnh và không cần thiết vì mọi Unix đi kèm bcđã cung cấp dịch vụ này cho bạn theo cách tương đối dễ dàng và dễ tiếp cận.
read a < a.txt. Điều đó cũng sẽ quan tâm đến việc tước bỏ khoảng trống hàng đầu và dấu vết nếu có (giả sử $IFSchưa được sửa đổi).
                    echo "\"hello\"", thứ bên trong $(...)không phải là một chuỗi được truyền dưới dạng đối số cho một chương trình khác và shell biết cách xử lý các dấu ngoặc kép. Đây cũng là lý do tại sao sử dụng $(...)chứ không phải backticks là tốt hơn; bạn có thể viết $( ... $( ... ) )mà không có bất kỳ sự mơ hồ nào, trong khi điều tương tự sử dụng backticks là ... khó xử.
                    bc.
                    Như cả Stéphane và Kusalananda đều nói , "thực sự, chỉ sử dụng bc", nhưng nếu bạn thực sự muốn sử dụng bash để thêm vào, thì đây là điểm khởi đầu (chỉ số nguyên dương) - Tôi sẽ để nó như một bài tập để người đọc thực hiện số thập phân và số âm:
function arbadd {
  addend1=$1
  addend2=$2
  sum=
  bcsum=$(echo $addend1 + $addend2 | BC_LINE_LENGTH=0 bc)
  # zero-pad the smallest number
  while [ ${#addend1} -lt ${#addend2} ]
  do
    addend1=0${addend1}
  done
  while [ ${#addend2} -lt ${#addend1} ]
  do
    addend2=0${addend2}
  done
  carry=0
  for((index=${#addend1}-1;index >= 0; index--))
  do
    case ${carry}${addend1:index:1}${addend2:index:1} in
      (000) carry=0; sum=0${sum};;
      (001|010|100) carry=0; sum=1${sum};;
      (002|011|020|101|110) carry=0; sum=2${sum};;
      (003|012|021|030|102|111|120) carry=0; sum=3${sum};;
      (004|013|022|031|040|103|112|121|130) carry=0; sum=4${sum};;
      (005|014|023|032|041|050|104|113|122|131|140) carry=0; sum=5${sum};;
      (006|015|024|033|042|051|060|105|114|123|132|141|150) carry=0; sum=6${sum};;
      (007|016|025|034|043|052|061|070|106|115|124|133|142|151|160) carry=0; sum=7${sum};;
      (008|017|026|035|044|053|062|071|080|107|116|125|134|143|152|161|170) carry=0; sum=8${sum};;
      (009|018|027|036|045|054|063|072|081|090|108|117|126|135|144|153|162|171|180) carry=0; sum=9${sum};;
      (019|028|037|046|055|064|073|082|091|109|118|127|136|145|154|163|172|181|190) carry=1; sum=0${sum};;
      (029|038|047|056|065|074|083|092|119|128|137|146|155|164|173|182|191) carry=1; sum=1${sum};;
      (039|048|057|066|075|084|093|129|138|147|156|165|174|183|192) carry=1; sum=2${sum};;
      (049|058|067|076|085|094|139|148|157|166|175|184|193) carry=1; sum=3${sum};;
      (059|068|077|086|095|149|158|167|176|185|194) carry=1; sum=4${sum};;
      (069|078|087|096|159|168|177|186|195) carry=1; sum=5${sum};;
      (079|088|097|169|178|187|196) carry=1; sum=6${sum};;
      (089|098|179|188|197) carry=1; sum=7${sum};;
      (099|189|198) carry=1; sum=8${sum};;
      (199) carry=1; sum=9${sum};;
    esac
  done
  if [ $carry -eq 1 ]
  then
    sum=1${sum}
  fi
  printf "Sum = %s\n" "$sum"
}Tôi đã để lại sự bcso sánh trong đó, nhưng nhận xét, để so sánh.
pythonhoặc tương tự trong trường hợp đó.