일반 관계 연산자 '

일반 관계 연산자 '

다음과 같은 파일이 있습니다.

0.2
0.2
0.2
0.2
0.2
0.2
0.2024
0.2025
0.2027
0.2027
0.2029
0.2059
0.2059
0.2059
0.2059
0.2099
0.2099
0.2099
0.2105
0.2113
0.2113
0.2195
0.2198
0.2206
0.2206
0.2206
0.2989
0.2989
0.2989
0.3
0.3

그리고 범위에 포함된 값의 수를 계산하고 싶습니다. 예:

0.2 18
0.21 5
0.22 3
0.23 0
0.24 0
0.25 0
0.26 0
0.27 0
0.28 0
0.29 3
0.3 2

보시다시피 저는 0.01 간격을 사용합니다. 나는 awk그것을 달성하기 위해 사용하고 있지만 이상한 동작이 발생합니다.

awk 'BEGIN {for (i=0;i<1.01;i+=0.01) a[i]=0} {
    for (j=0;j<=1;j+=0.01) 
      if($1>=j && $1<j+0.01) {
        a[j]+=1
      }
    } 
    END {for (k=0;k<1.01;k+=0.01) print k,a[k]}' test_OH.txt

결과:

0.19 6
0.2 12
0.21 5
0.22 3
0.23 0
0.24 0
0.25 0
0.26 0
0.27 0
0.28 0
0.29 5
0.3 0

누구든지 나를 도와줄 수 있나요? <가 만족되기 때문에 예상대로 작동하지 않는 것 같습니다 $1 == j+0.01. 물론, 나는 아무것도 고려하고 있지 않습니다. 감사합니다!

답변1

awk -v s=0.2 -v e=0.3 -v d=0.01 '
   BEGIN { m = 1/d }
   { a[int($1*m)]++ }
   END{ e *= m; for(s = int(s*m); s <= e; s++) print s*d, a[s]+0 }
' test_OH.txt

0.2 18
0.21 5
0.22 3
0.23 0
0.24 0
0.25 0
0.26 0
0.27 0
0.28 0
0.29 3
0.3 2

( 시작 s) e(끝) 및 d(델타/단계) 변수는 필요에 따라 조정될 수 있습니다.


  1. 반복적으로 추가하여 범위를 생성하는 것은 0.01부동 소수점 숫자로 수행하지 말아야 할 작업에 대한 거의 교과서적인 예입니다. 왜냐하면 0.012진수로 정확하게 표현할 수 없고 추가할 때마다 오류가 누적되기 때문입니다.

  2. 각 라인의 전체 범위를 스캔하는 것은 비효율적이고 의미가 없습니다.

  3. ""awk의 변수는 또는 로 초기화될 필요가 없습니다 0.

답변2

이거 한번 해봐:

awk '
  BEGIN {for (i=0;i<1.01;i+=0.01) a[i]=0}
  {
    n = int($1 * 100) / 100
    a[n] += 1
  }
  END {for (k=0;k<1.01;k+=0.01) print k,a[k]}'

또는 이것은 이해하기 어렵다고 생각합니다.

awk 'BEGIN {for (i=0;i<1.01;i+=0.01) a[i]=0} {
    for (j=0;j<=1;j+=0.01)
      if(("X" $1 >= "X" j) && ("X" $1 < "X" j+0.01)) {
        a[j]+=1
      }
    }
    END {for (k=0;k<1.01;k+=0.01) print k,a[k]}'

원본이 작동하지 않는 이유는 위의 Quasimodo의 발언을 참조하십시오.

답변3

이 내용을 답변으로 게시해야 할지 댓글로 게시해야 할지 잘 모르겠지만, 다음은 내 컴퓨터에서 이 경우 부정확성과 결과 숫자에 대한 간단한 데모입니다.

$ awk 'BEGIN { d = 0.01; printf "%.20f\n", d; for (i = 0; i < 30; i++) a += d; printf "%.20f\n%.20f\n", 0.3, a }'   
0.01000000000000000021
0.29999999999999998890
0.30000000000000009992

첫 번째 숫자는 0.01이 실제로 저장되는 숫자입니다. 1/100에는 1/5 요소가 포함되어 있고 이진수로 표현할 수 없기 때문에 정확하지 않습니다.

두 번째는 0.3이 저장되는 것이고, 세 번째는 0.01이 30번 더해진 것입니다. ( 0.01 * 30모든 단계에 중간 반올림이 있기 때문에 동일하지는 않습니다 .)

다른 답변에는 해결책이 있으므로 찬성 투표하세요.

관련 정보