2013-02-13 76 views
14

awkの2つの数値を整数除算、つまり結果を切り捨てることで除算したいと考えています。例えばawkの整数除算

k = 3/2 
print k 

the manualによると1

部門を印刷する必要があります。 awkではすべての数値は浮動小数点数であるため、結果は

整数に四捨五入されていない整数値を取得するための任意の回避策はありますか?

理由は、I [0 NUM-1] 整数インデックスを持つ配列の中間要素を取得したいということです。

答えて

27

これは、例えば、結果と0との間に位置する結果に最も近い整数を生成int(3/2)が1である、int(-3/2)は-1 0に向かって切り捨て、結果の整数部を取得するint関数を使用します。

出典:簡単な例でThe AWK Manual - Numeric Functions

4

、あなたが安全にゼロに向けて切り捨てたint()を使用することができます。

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

は、倍精度浮動小数点数2を使用して、常にawkのことに注意してくださいと浮動小数点演算です。整数と整数の算術演算を行う唯一の方法は、外部ツールを使用することです。標準exprユーティリティ:

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

は、これは本当にawkの区、長い、遅い、...しかし、安全かつポータブルです。 POSIX awk


、ゼロに切り捨てのみ正の引数について保証される:INT(X) - 整数に切り捨てられた引数を返します。 x> 0の場合、切り捨ては0に向かうものとする。GNU awk(gawk)は、負の数値に対してもゼロに向かって切り捨てを使用します。int(x) - xとゼロの間に位置し、ゼロに切り捨てられたxに最も近い整数を返します。たとえば、int(3)は3、int(3.9)は3、int(-3.9)は-3、int(-3)も-3です。
数値式は、POSIXのExpressions in awkで倍精度浮動小数点数として指定されています。
すべての算術演算は、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. Wikipediaの記事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これは 'ceil'型の丸め(+ infに向かって)を実装しています。他の数学的に正しいmodの概念とその結果、丸め方法が存在する。他の方法が好ましい場合もある。 – sorontar

    +0

    @sorontar少なくとも私のシステムでは、これは 'ceil'関数と等価ではありません –