Tôi vẫn đang tìm kiếm một bc
câ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 bash
câ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**10
in 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ó để $int
và 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 $int
và $fraction
và sau đó điều chỉnh đó để phù hợp với độ chính xác (ví dụ như embiggen 48.86
trở thành 10¹⁰ × 4886/100 và lợi nhuận 488600000000
mà 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 $int
giá trị mới để $answer
loại trừ hai chữ số cuối cùng của nó, sau đó echo
là một dấu chấm và $answer
loại trừ $int
giá 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 zsh
là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.)