bc
함수 내에서 하나의 값만 반올림하는 방법 에 대한 순수한 대답을 찾고 있지만 순수한 bash
대답은 다음과 같습니다.
#!/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..."
기본적으로 이것은 소수점을 조심스럽게 추출하고 모든 것을 1,000 억 (10¹ 10**10
in bash
)으로 곱하고 정밀도와 반올림을 조정하고 실제 나누기를 수행하고 적절한 크기로 다시 나누고 소수점을 다시 삽입합니다.
단계별 :
이 embiggen()
함수는 잘린 정수 형식의 인수를 할당하고 $int
에 점 다음에 숫자를 저장합니다 $fraction
. 소수 자릿수는에 표시되어 $precision
있습니다. 수학의 연결에 의해 곱 10¹⁰ $int
와 $fraction
후와 그 예는 (정밀도에 맞게 조정 embiggen 48.86
10¹⁰ × 100분의 4,886 반환된다488600000000
488,600,000,000)입니다.
우리는 100 분의 1의 정밀도를 원하므로 첫 번째 숫자에 100을 곱하고 반올림 목적으로 5를 더한 다음 두 번째 숫자를 나눕니다. 이 임무는 $answer
우리에게 최종 답변의 백 배 를 남깁니다.
이제 소수점을 추가해야합니다. 우리는 새로운 지정 $int
에 가치를 $answer
다음의 마지막 두 자리를 제외 echo
점으로 그것을하고 $answer
제외$int
이미 알아서 값을. (이것이 주석처럼 보이게하는 구문 강조 버그는 신경 쓰지 마십시오)
(Bashism : 지수화는 POSIX가 아니므로 이것은 bashism입니다. 순수한 POSIX 솔루션은 10의 거듭 제곱을 사용하는 대신 0을 추가하기 위해 루프를 필요로합니다. 또한 "embiggen"은 완벽하게 cromulant 단어입니다.)
zsh
쉘로 사용하는 주된 이유 중 하나 는 부동 소수점 수학을 지원하기 때문입니다. 이 질문에 대한 해결책은 다음과 같이 매우 간단합니다 zsh
.
printf %.2f $((float/1.18))
(누군가에서 부동 소수점 산술을 활성화하는 트릭 으로이 답변에 의견을 추가하고 싶지만 bash
그러한 기능이 아직 존재하지 않는다는 것을 확신합니다.)