2013-02-13 2 views
14

awk에 두 개의 숫자를 정수 나누기로 나누고 싶습니다. 즉, 결과를 자릅니다. 예를 들어awk의 정수 나누기

k = 3/2 
print k 

the manual 따르면

부로 1

를 출력한다; AWK의 모든 숫자는 숫자 부동 소수점 때문에, 결과는 정수

정수 값을 얻을 수있는 해결 방법은 반올림하지?

이유

내가 [NUM-1 0] 정수 인덱스 배열의 중간 소자를 얻으려면 점이다.

답변

27

int(-3/2)은 -1, int(3/2)는 1, 그 결과, 예를 들면 0 사이에있는 결과에 가장 가까운 정수를 생산 0쪽으로 절단 결과의 정수 부분을 얻기 위해 int 함수를 사용한다.

출처 : 간단한 경우 The AWK Manual - Numeric Functions

4

, 안전하게 제로 1으로 절단하는 int()를 사용할 수 있습니다 항상 awk가 명심

awk 'BEGIN { print int(3/2) }' # prints 1 
gawk 'BEGIN { print int(-3/2) }' # prints -1; not guaranteed in POSIX awk 

은 부동 소수점 숫자를 배정 밀도를 사용 및 부동 소수점 연산 . 정수와 정수 연산을 얻는 유일한 방법은 외부 도구를 사용하는 것입니다. 표준 expr 유틸리티 :

awk 'BEGIN { "expr 3/2" | getline result; print result; }' # prints 1 

이 정말 천천히 ... 그러나 안전 및 휴대용 긴 AWK 병동,이다. POSIX awk에서

1


은 0으로 절단은 긍정적 인 인수 보장 : INT (x)는 - 정수로 잘립니다 인수를 돌려줍니다. 절단은 x> 0 인 경우 0을 향해야합니다. GNU awk (gawk)은 음수에도 제로를 잘라냅니다. int (x) - x와 0 사이에있는 x에 가장 가까운 정수를 반환하고 0으로 잘립니다. 예를 들어, int (3)은 3, int (3.9)는 3, int (-3.9)는 -3, int (-3)은 -3입니다.
숫자 식은 POSIX의 Expressions in awk에서 배정도 부동 소수점으로 지정됩니다.
3 모든 산술은 ISO C 표준에서 규정 된 부동 소수점 연산의 의미 (Concepts Derived from the ISO C Standard 참조)에 따른다. - 당신이 수레를 사용하도록 선택하는 경우 POSIX awk: Arithmetic functions


, 당신은 자신의 단점에 대해 알고 그들을 파악하고 관련 버그를 방지 할 준비가되어 있어야합니다. 몇 가지 무서운 예 :

  • 표현할 수없는 번호 :

    awk 'BEGIN { x = 0.875; y = 0.425; printf("%0.17g, %0.17g\n", x, y) }' 
    # prints 0.875, 0.42499999999999999 
    
  • Round-off errors 축적 :

    awk 'BEGIN{s=0; for(i=1;i<=100000;i++)s+=0.3; printf("%.10f, %d\n",s,int(s))}' 
    # prints 29999.9999999506, 29999 
    
  • 반올림 오류가 파괴 비교 :

    awk 'BEGIN { print (0.1 + 12.2 == 12.3) }' # prints 0 
    
  • 정밀은 무한 루프의 원인, 크기 감소 :

    1. 스택 오버플로 태그 위키

    2. 위키 백과 문서 Floating point

    3. : 더 많은 작업 수레 방법에 대해 자세히

      awk 'BEGIN { for (i=10^16; i<10^16+5; i++) printf("%d\n", i) }' 
      # prints 10000000000000000 infinitely many times 
      

  • GNU awk arbitrary precision arithmetic은 - 특정 구현 및 일반적인 지식에 모두 정보를 포함

  • +0

    내가 상대적으로 위해 (부동 오류를 극복 할 수있는 방법을 생각 작은 수)는'int (3/2 + 0.25)'를하는 것입니다. – user000001

    +0

    @ user000001 상수를 추가해도 문제가 해결되지 않고 실제로 상수가 추가됩니다. 'awk 'BEGIN {print int (7/8), int (7/8 + 0.25)}'는 '0 1'을 생성합니다. – Palec

    +0

    예 '1/(d/2)'보다 작아야합니다. 여기서'd '는 분모입니다. 이 값이 부동 오류보다 큰 경우 작동해야합니다. – user000001

    5

    안전하고 빠른 AWK 정수 부문으로 수행 할 수 있습니다

    q=(n-n%d)/d+(n<0) 
    
    +0

    +1. 영리한 속임수, 내가 너에게 줄께. 나는 정확한 오류에 대해 안전한지 궁금해한다. @Palec이 설명하기 때문에 ... – user000001

    +0

    +1 이것은 (ceiling) 반올림 유형을 구현한다. 다른 수학적으로 올바른 mod 개념과 결과적으로 반올림 방법이 존재합니다. 다른 방법이 바람직 할 수 있습니다. – sorontar

    +0

    @sorontar 적어도 내 시스템에서는 이것은 ceil 함수와 같지 않다. –