10

複数のフィールドを持つパイプ区切りのフィード ファイルがあります。少数しか必要ないのでawk、テスト目的でそれらをキャプチャするために使用することを考えました. printfしかし、を使用すると値が変わることに気付きました"%d"。を使えばうまくいきます"%s"

フィード ファイルのサンプル:

[jaypal:~/Temp] cat temp

302610004125074|19769904399993903|30|15|2012-01-13 17:20:02.346000|2012-01-13 17:20:03.307000|E072AE4B|587244|316|13|GSM|1|SUCC|0|1|255|2|2|0|213|2|0|6|0|0|0|0|0|10|16473840051|30|302610|235|250|0|7|0|0|0|0|0|10|54320058002|906|722310|2|0||0|BELL MOBILITY CELLULAR, INC|BELL MOBILITY CELLULAR, INC|Bell Mobility|AMX ARGENTINA SA.|Claro aka CTI Movil|CAN|ARG|

をキャプチャすることに興味がsecond columnあり19769904399993903ます。

ここに私のテストがあります:

[jaypal:~/Temp] awk -F"|" '{printf ("%d\n",$2)}' temp
19769904399993904   # Value is changed

ただし、次の 2 つのテストは問題なく動作します -

[jaypal:~/Temp] awk -F"|" '{printf ("%s\n",$2)}' temp
19769904399993903   # Value remains same

[jaypal:~/Temp] awk -F"|" '{print $2}' temp
19769904399993903   # Value remains same

これは、"%d"長い整数を処理できないという制限です。その場合、番号を切り捨てるのではなく、番号に 1 を追加するのはなぜですか?

BSDGNUのバージョンでこれを試しましたawk

バージョン情報:

[jaypal:~/Temp] gawk --version
GNU Awk 4.0.0
Copyright (C) 1989, 1991-2011 Free Software Foundation.

[jaypal:~/Temp] awk --version
awk version 20070501
4

7 に答える 7

5

この場合の基本的な数値形式は、IEEE double であると思います。したがって、変更された値は浮動小数点精度エラーの結果です。大きな値を数値として扱い、正確な精度を維持することが実際に必要な場合は、Perl、Ruby、または Python など、任意精度の演算を処理する機能 (おそらく拡張機能を介して) を使用する方がよい場合があります。

于 2012-01-13T22:17:20.520 に答える
4

この回答は、@Mark Wilkins と @Dennis Williamson によってすでに部分的に回答されていますが、精度を失うことなく処理できる最大の 64 ビット整数は 2^53 であることがわかりました。例 awk のリファレンス ページ http://www.gnu.org/software/gawk/manual/gawk.html#Integer-Programming

(私の答えが古すぎる場合は申し訳ありません。次の人が私のようにこれに多くの時間を費やす前に、まだ共有すると思います)

于 2014-02-26T01:31:25.420 に答える
4

更新: GNU awk の最近のバージョンでは、任意精度の演算がサポートされています。詳細については、GNU awk マニュアルを参照してください。

元の投稿コンテンツ: XMLgawk は、浮動小数点数の任意精度演算をサポートしています。したがって、xgawkのインストールがオプションの場合:

zsh-4.3.11[drado]% awk --version |head -1; xgawk --version | head -1
GNU Awk 4.0.0
Extensible GNU Awk 3.1.6 (build 20080101) with dynamic loading, and with statically-linked extensions

zsh-4.3.11[drado]% awk 'BEGIN {
  x=665857
  y=470832
  print x^4 - 4 * y^4 - 4 * y^2
  }'
11885568

zsh-4.3.11[drado]% xgawk -lmpfr 'BEGIN {
  MPFR_PRECISION = 80
  x=665857
  y=470832
  print mpfr_sub(mpfr_sub(mpfr_pow(x, 4), mpfr_mul(4, mpfr_pow(y, 4))), 4 * y^2)
  }'
1.0000000000000000000000000
于 2012-01-15T13:01:42.533 に答える
1

Awkの Floating Point Representation Issuesが発生しています。awk フレームワーク内で、膨大な数の算術演算を正確に実行するための回避策を見つけることができるとは思いません。

私が考えることができる唯一の可能な(そして大雑把な)方法は、膨大な数を小さなチャンクに分割し、計算を実行してそれらを再度結合するか、または awk よりも強力な Perl/PHP/TCL/bsh などのスクリプト言語を使用することです。

于 2012-01-13T22:28:38.783 に答える