This page is READ-ONLY. It is generated from the old site.
All timestamps are relative to 2013 (when this page is generated).
If you are looking for TeX support, please go to VietTUG.org

so sánh các số thực trong bourne/bash

lolz
Added by almost 3 years ago  »  Votes: 2/2

Khi lập trình kịch bản với Bourne hay Bash, bạn có thể sử dụng test hoặc [ hoặc [[ để so sánh các số nguyên. Với các số thực thì sao?

1 #!/bin/bash
2 $ if [ 1.2 -eq 3 ]; then echo 1; fi
3 bash: [: 1.2: integer expression expected
4 
5 # Nếu dùng [[ thì sẽ nhận lỗi sau
6 bash: [[: 1.2: syntax error: invalid arithmetic operator (error token is ".2")

Cách vượt qua trở ngại này là dùng các chương trình ngoài, như bc, awk.

Đầu tiên là phiên bản awk. Hàm ge sẽ kiểm tra xem số thứ nhất nhỏ hay bằng số thứ hai, và trả về kết quả 0 nếu đúng.

1 # kiểm tra $a có nhỏ hơn hay bằng $b?
2 $ ge() { echo | awk -vA="$1" -vB="$2" '{if (A <= B) {exit 0} else {exit 1}}' ;}
3 $ ge 1.2 1.3; echo $?                       # in ra 0
4 $ ge 1.4 1.3; echo $?                       # in ra 1
5 $ if `ge 1.2 1.3`; then echo "lesser"; fi   # in ra lesser

Để dùng bc, thì có một phiền toái nhỏ với mã thoát: bc luôn trả về 0 nếu nó xử hết được các mã nhập vào; ta không thể thay đổi kết quả trả về giống như cách dùng awk ở trên.

1 # đây là Bash; bc sẽ in ra 1 nếu $1 <= $2
2 $ gebc() { if [ $(echo "$1 <= $2" | bc) -eq 1 ]; then return 0; else return 1; fi ;}

Lưu ý rằng, cả hai phiên bản ở trên sẽ sinh kết quả sai nếu đầu vào không thật sự là các con số ;)


Comments

Added by bronzeboyvn almost 3 years ago

Đúng hơn là dùng bc, awk để "chữa cháy" khi thực hiện phép toán với số thực trên bash. Gặp yêu cầu như vậy, cách hữa hiệu hơn cả là dùng zsh hoặc ksh.
Còn với bài toán so sánh, ta vẫn có thể thực hiện trên bash mà không cần "nhờ vả":

 1 #!/bin/bash
 2 
 3 a=3.14
 4 echo "a = $a" 
 5 b=4.13
 6 echo "b = $b" 
 7 diff=`expr $a '<' $b`
 8 equal=`expr $a '==' $b`
 9 if [ $equal -eq 1 ]; then
10    echo "$a = $b" 
11 elif [ $diff -eq 1 ]; then
12    echo "$a < $b" 
13 elif [ $diff -eq 0 ]; then
14    echo "$a > $b" 
15 else
16    echo "Don't reach here" 
17 fi

Cách này bị một khuyết điểm kiểu này 1.0 .

Added by almost 3 years ago

  1. Các shell như zsh hay ksh không phổ biến như sh (trên BSD) và bash (trên Linux) :)
  2. expr cũng không phải là một hàm builtin của Bash. Cộng với khuyết điểm mà CT nói thì chắc là không thể dùng rồi ;) Trên FreeBSD thì tài liệu man của expr chỉ nói tới việc dùng nó cho việc thực hiện các phép toán số học trên số nguyên có dấu