bash
Trong bashđó, có lẽ là tốt như nó được. Điều đó sử dụng một vỏ dựng sẵn. Nếu bạn cần kết quả trong một biến, bạn có thể sử dụng thay thế lệnh hoặc bashcụ thể (mặc dù hiện tại cũng được hỗ trợ bởi zsh):
printf -v int %.0f "$float"
Bạn có thể làm:
float=1.23
int=${float%.*}
Nhưng điều đó sẽ loại bỏ phần phân số thay vì cung cấp cho bạn số nguyên gần nhất và điều đó sẽ không hoạt động đối với các giá trị $floattương tự 1.2e9hoặc .12chẳng hạn.
Cũng lưu ý các hạn chế có thể do biểu diễn bên trong của phao:
$ printf '%.0f\n' 1e50
100000000000000007629769841091887003294964970946560
Bạn nhận được một số nguyên, nhưng rất có thể bạn sẽ không thể sử dụng số nguyên đó ở bất cứ đâu.
Ngoài ra, như được lưu ý bởi @BinaryZebra, trong một số printftriển khai (bash, ksh93, yash, không phải GNU, zsh, dash), nó bị ảnh hưởng bởi miền địa phương (dấu tách thập phân có thể .hoặc ,).
Vì vậy, nếu số float của bạn luôn được biểu thị bằng dấu phân cách thập phân và bạn muốn nó được xử lý như vậy bằng cách printfbất kể ngôn ngữ của người dùng gọi tập lệnh của bạn, bạn cần sửa ngôn ngữ thành C:
LC_ALL=C printf '%.0f' "$float"
Với yash, bạn cũng có thể làm:
printf '%.0f' "$(($float))"
(xem bên dưới).
MỘT BỘ MÔ TẢ CHÍNH THỨC CUNG CẤP MỘT TIÊU CHUẨN CHO THIẾT KẾ HỆ ĐIỀU HÀNH, ĐẶC BIỆT LÀ CÁC MÔ TẢ TƯƠNG THÍCH VỚI UNIX
printf "%.0f\n" 1.1
không phải là POSIX vì %fkhông bắt buộc phải được POSIX hỗ trợ.
POSIXly, bạn có thể làm:
f2i() {
awk 'BEGIN{for (i=1; i<ARGC;i++)
printf "%.0f\n", ARGV[i]}' "$@"
}
Cái đó không bị ảnh hưởng bởi miền địa phương (dấu phẩy không thể là dấu phân cách thập phân awkvì nó đã là một ký tự đặc biệt trong cú pháp ở đó ( print 1,2giống như print 1, 2để truyền hai đối số cho print)
zsh
Trong zsh(hỗ trợ số học dấu phẩy động (dấu tách thập phân luôn luôn là dấu chấm)), bạn có rint()hàm toán học để cung cấp cho bạn số nguyên gần nhất dưới dạng float (như in C) và int()cung cấp cho bạn một số nguyên từ float (như in awk). Vì vậy, bạn có thể làm:
$ zmodload zsh/mathfunc
$ i=$((int(rint(1.234e2))))
$ echo $i
123
Hoặc là:
$ integer i=$((rint(5.678e2)))
$ echo $i
568
Tuy nhiên lưu ý rằng trong khi doubles có thể đại diện cho số lượng rất lớn, số nguyên bị giới hạn hơn nhiều.
$ printf '%.0f\n' 1e123
999999999999999977709969731404129670057984297594921577392083322662491290889839886077866558841507631684757522070951350501376
$ echo $((int(1e123)))
-9223372036854775808
ksh93
ksh93 là lớp vỏ giống như Bourne đầu tiên hỗ trợ số học dấu phẩy động. ksh93 tối ưu hóa thay thế lệnh bằng cách không sử dụng đường ống hoặc rèn khi các lệnh chỉ là các lệnh dựng sẵn. Vì thế
i=$(printf '%.0f' "$f")
không ngã ba. Hoặc thậm chí tốt hơn:
i=${ printf '%.0f' "$f"; }
điều này cũng không làm ngã ba nhưng cũng không gặp phải rắc rối nào khi tạo môi trường subshell giả.
Bạn cũng có thể làm:
i=$((rint(f)))
Nhưng hãy cẩn thận với:
$ echo "$((rint(1e18)))"
1000000000000000000
$ echo "$((rint(1e19)))"
1e+19
Bạn cũng có thể làm:
integer i=$((rint(f)))
Nhưng thích cho zsh:
$ integer i=1e18
$ echo "$i"
1000000000000000000
$ integer i=1e19
$ echo "$i"
-9223372036854775808
Coi chừng ksh93số học dấu phẩy động tôn vinh cài đặt dấu phân cách thập phân ở miền địa phương (mặc dù đó ,là toán tử toán học ( $((1,2))sẽ là 6/5 ở miền địa phương Pháp / Đức ... và tương tự $((1, 2)), đó là 2 trong một ngôn ngữ tiếng Anh) .
yash
yash cũng hỗ trợ số học dấu phẩy động nhưng không có các hàm toán học như ksh93/ zsh's rint(). Bạn có thể chuyển đổi một số thành số nguyên mặc dù bằng cách sử dụng nhị phân hoặc toán tử (cũng hoạt động zshnhưng không hoạt động ksh93). Tuy nhiên, xin lưu ý rằng nó cắt bớt phần thập phân, nó không cung cấp cho bạn số nguyên gần nhất:
$ echo "$((0.237e2 | 0))"
23
$ echo "$((1e19))"
-9223372036854775808
yash tôn vinh dấu phân cách thập phân của miền địa phương trên đầu ra, nhưng không cho các hằng số nghĩa đen của dấu phẩy động trong các biểu thức số học của nó, điều này có thể gây ra sự ngạc nhiên:
$ LC_ALL=fr_FR.UTF-8 ./yash -c 'a=$((1e-2)); echo $(($a + 1))'
./yash: arithmetic: `,' is not a valid number or operator
Theo cách tốt, bạn có thể sử dụng các hằng số dấu phẩy động trong các tập lệnh sử dụng dấu chấm và không phải lo lắng rằng nó sẽ ngừng hoạt động ở các địa phương khác, nhưng vẫn có thể xử lý các số được người dùng thể hiện miễn là như bạn nhớ làm:
var=$((10.3)) # and not var=10.3
... "$((a + 0.1))" # and not "$(($a + 0.1))".
printf '%.0f\n' "$((10.3))" # and not printf '%.0f\n' 10.3