(GNU) awk (bignum이 컴파일 된 상태)로 더 높은 정밀도를 얻으려면 다음을 사용하십시오.
$ echo '0.4970436865354813' | awk -M -v PREC=100 '{printf("%.18f\n", $1)}'
0.497043686535481300
PREC = 100은 기본 53 비트 대신 100 비트를 의미합니다.
해당 awk를 사용할 수 없으면 bc를 사용하십시오.
$ echo '0.4970436865354813*1.1' | bc -l
.54674805518902943
또는 수레의 고유 한 부정확성을 가지고 사는 법을 배워야합니다.
원래 줄에는 몇 가지 문제가 있습니다.
- 1.1의 인수는 1 %가 아니라 10 % 증가한 것입니다 (1.01 배수 여야 함). 10 %를 사용하겠습니다.
문자열에서 (부동) 숫자로의 변환 형식은 CONVFMT에 의해 제공됩니다. 기본값은 %.6g
입니다. 값이 소수점 이하 6 자리로 제한됩니다. 이는의 gsub 변경 결과에 적용됩니다 $1
.
$ a='0.4970436865354813'
$ echo "$a" | awk '{printf("%.16f\n", $1*1.1)}'
0.5467480551890295
$ echo "$a" | awk '{gsub($1, $1*1.1)}; {printf("%.16f\n", $1)}'
0.5467480000000000
printf 형식 g
은 후행 0을 제거합니다.
$ echo "$a" | awk '{gsub($1, $1*1.1)}; {printf("%.16g\n", $1)}'
0.546748
$ echo "$a" | awk '{gsub($1, $1*1.1)}; {printf("%.17g\n", $1)}'
0.54674800000000001
두 가지 문제를 모두 해결할 수 있습니다.
$ echo "$a" | awk '{printf("%.17g\n", $1*1.1)}'
0.54674805518902947
또는
$ echo "$a" | awk -v CONVFMT=%.30g '{gsub($1, $1*1.1)}; {printf("%.17f\n", $1)}'
0.54674805518902947
그러나 이것이 더 높은 정밀도를 의미한다는 생각을하지 마십시오. 내부 숫자 표현은 여전히 두 배 크기의 부동입니다. 즉, 정밀도는 53 비트이며 최대 17 자리가 여러 번 올바르게 표시 되더라도 15 자리의 정확한 10 진수 만 확신 할 수 있습니다. 신기루입니다.
$ echo "$a" | awk -v CONVFMT=%.30g '{gsub($1, $1*1.1}; {printf("%.30f\n", $1)}'
0.546748055189029469325134868996
올바른 값은 다음과 같습니다.
$ echo "scale=18; 0.4970436865354813 * 1.1" | bc
.54674805518902943
bignum 라이브러리가 다음과 같이 컴파일 된 경우 (GNU) awk로 계산할 수도 있습니다.
$ echo "$a" | awk -M -v PREC=100 -v CONVFMT=%.30g '{printf("%.30f\n", $1)}'
0.497043686535481300000000000000