둥근 부동 소수점 숫자

둥근 부동 소수점 숫자

명령줄에서 IEEE 754 부동 소수점 숫자를 올바르게 반올림하는 방법은 무엇입니까?

출력 숫자의 정밀도(소수점 이하 자릿수)를 지정하고 싶습니다.

예를 들어 6.66정밀도에 맞게 반올림 1해야 합니다. 6.7자세한 내용은 아래 표를 참조하세요.

Value   Precision  Rounded
6.66    0          7
6.66    1          6.7
6.66    2          6.66
6.66    3          6.660
6.666   3          6.666
6.6666  3          6.667

이는 대화형 셸에서 작동해야 하지만 이상적으로는 프로덕션 셸 스크립트에서 사용할 수 있을 만큼 강력합니다.

답변1

둥근 부동 소수점 숫자

"부동 소수점 수 반올림"이란 무엇을 의미합니까?
간단한 것 같군요... 우리 학교 수학책은 어디에 있나요...

아니요, 우리는 부동 소수점 숫자와 관련된 일이 쉽지 않다는 것을 이미 알고 있습니다.

첫째, 다양한 반올림 모드가 있습니다.

모으다?
반올림 하시겠습니까?
0으로 반올림하시겠습니까?
가장 가까운 값으로 반올림 - 짝수인가요?
가장 가까운 값으로 반올림 - 0에서 멀어지나요?

극단적인 상황에 대처하는 방법은 무엇입니까? 어떤 경우가 극단적인 경우인지 어떻게 알 수 있나요?

좋습니다. IEEE 754 표준 구현을 사용하고 시스템에서 이를 처리하도록 하는 것이 더 나을 것 같습니다.

표준 부동 소수점 산술을 기반으로 셸에서 부동 소수점 숫자를 반올림하려면 다음 세 단계가 필요합니다.

  • 명령줄 인수의 입력 텍스트를 표준 부동 소수점 숫자로 변환합니다.
  • 부동 소수점 숫자는 일반적인 IEEE 754 구현을 사용하여 반올림됩니다.
  • 출력을 위해 숫자를 문자열로 형식화합니다.

쉘 명령으로 밝혀졌습니다printf모든 것을 할 수 있습니다. 에 설명된 대로 형식 사양에 따라 숫자를 인쇄하는 데 사용할 수 있습니다.man 3 printf. 출력 형식에서 요구하는 경우 숫자는 표준 방식으로 암시적으로 반올림됩니다.

주문하다

입력을 명령줄 인수로 사용하여 x숫자 정밀도로 반올림합니다.p

printf "%.*f\n" "$p" "$x"

또는 셸 파이프라인에서 x표준 입력을 입력 및 p인수로 사용합니다.

echo "$x" | xargs printf "%.*f\n" "$p"

예:

$ printf '%.*f\n' 0 6.66
7
$ printf '%.*f\n' 1 6.66
6.7
$ printf '%.*f\n' 2 6.66
6.66
$ printf '%.*f\n' 3 6.66
6.660
$ printf '%.*f\n' 3 6.666
6.666
$ printf '%.*f\n' 3 6.6666
6.667

나쁜 함정

영토를 조심하세요! .예상한 대로 정수 부분과 분수 부분 사이의 구분 기호를 지정합니다.
하지만 독일어 로케일에서는 어떤 일이 일어나는지 확인해 보세요. 예를 들면 다음과 같습니다.

$ LC_ALL=de_DE.UTF-8 printf '%.*f\n' 3 6.6666
6,667

네, 맞아요. 6,667쉼표 여섯 여섯 여섯 일곱. 이것은 확실히 스크립트를 엉망으로 만들 것입니다.
(그러나 독일의 두 고객에게만 해당됩니다. 현재 해당 고객을 위해 디버깅 중인 개발자 컴퓨터는 예외입니다.)

더 강하게

더욱 강력하게 만들려면 다음을 사용하세요.

LC_ALL=C /usr/bin/printf "%.*f\n" "$p" "$x"

또는

echo "$x" | LC_ALL=C xargs /usr/bin/printf "%.*f\n" "$p"

또한 변형 구현의 사소한 불일치를 해결하고 독일어 로케일로 설정했지만 내보낼 수 없는 경우 매우 더러운 효과를 방지하기 위해 /usr/bin/printf내장된 셸 대신 bashOR를 사용합니다. 그런 다음 내장된 을 사용 하고 ...zshprintfLC_ALL,/usr/bin/printf.


%g지정된 유효 숫자 수로 반올림을 참조하세요 .

답변2

내가 찾은 것을 깨끗하게 읽는 가장 쉬운 방법은 다음과 같습니다.

$ print "%.2f" $(bc <<< "0.10765432*100)
10.77

이제 5다음으로 변경하세요.4

10.76

읽기 쉽고 짧기 때문에 유지관리가 쉽습니다.

답변3

다음은 나를 위해 일했습니다.

#!/bin/bash
function float() {
bc << EOF
num = $1;
base = num / 1;
if (((num - base) * 10) > 1 )
    base += 1;
print base;
EOF
echo ""
}

float 3.2

관련 정보