Tôi vẫn đang tìm kiếm một bccâu trả lời thuần túy về cách làm tròn chỉ một giá trị trong một hàm, nhưng đây là một bashcâu trả lời thuần túy :
#!/bin/bash
echo "Insert the price you want to calculate:"
read float
echo "This is the price without taxes:"
embiggen() {
local int precision fraction=""
if [ "$1" != "${1#*.}" ]; then # there is a decimal point
fraction="${1#*.}" # just the digits after the dot
fi
int="${1%.*}" # the float as a truncated integer
precision="${#fraction}" # the number of fractional digits
echo $(( 10**10 * $int$fraction / 10**$precision ))
}
# round down if negative
if [ "$float" != "${float#-}" ]
then round="-5000000000"
else round="5000000000"
fi
# calculate rounded answer (sans decimal point)
answer=$(( ( `embiggen $float` * 100 + $round ) / `embiggen 1.18` ))
int=${answer%??} # the answer as a truncated integer
echo $int.${answer#$int} # reassemble with correct precision
read -p "Press any key to continue..."
Về cơ bản, điều này trích xuất cẩn thận các số thập phân, nhân mọi thứ với 100 tỷ (10¹⁰, 10**10in bash), điều chỉnh độ chính xác và làm tròn, thực hiện phép chia thực tế, chia lại cho độ lớn phù hợp và sau đó lắp lại số thập phân.
Từng bước một:
Các embiggen()chuyển nhượng chức năng cắt ngắn số nguyên dưới dạng đối số của nó để $intvà tiết kiệm các con số sau dấu chấm trong $fraction. Số chữ số phân số được ghi chú trong $precision. Multiplies toán 10¹⁰ bởi nối của $intvà $fractionvà sau đó điều chỉnh đó để phù hợp với độ chính xác (ví dụ như embiggen 48.86trở thành 10¹⁰ × 4886/100 và lợi nhuận 488600000000mà là 488.600.000.000).
Chúng tôi muốn độ chính xác cuối cùng là một phần trăm, vì vậy chúng tôi nhân số thứ nhất với 100, thêm 5 cho mục đích làm tròn, sau đó chia số thứ hai. Nhiệm vụ này $answerđể lại cho chúng tôi một trăm lần câu trả lời cuối cùng.
Bây giờ chúng ta cần thêm dấu thập phân. Chúng tôi gán một $intgiá trị mới để $answerloại trừ hai chữ số cuối cùng của nó, sau đó echolà một dấu chấm và $answerloại trừ $intgiá trị đã được xử lý. (Đừng bận tâm đến lỗi tô sáng cú pháp khiến lỗi này xuất hiện như một bình luận)
(Bashism: lũy thừa không phải là POSIX, vì vậy đây là một phép bashism. Một giải pháp POSIX thuần túy sẽ yêu cầu các vòng lặp để thêm số 0 thay vì sử dụng lũy thừa mười. Ngoài ra, "embiggen" là một từ hoàn hảo.
Một trong những lý do chính mà tôi sử dụng zshlàm vỏ của mình là nó hỗ trợ toán học dấu phẩy động. Giải pháp cho câu hỏi này khá đơn giản trong zsh:
printf %.2f $((float/1.18))
(Tôi rất muốn thấy ai đó thêm nhận xét cho câu trả lời này bằng mẹo để bật số học dấu phẩy động bash, nhưng tôi khá chắc chắn rằng một tính năng như vậy chưa tồn tại.)