awk中的strtonum导致值失去精度

liv*_*hak 2 bash awk

我有一个以下格式的文本文件.

1   0x5212cb03ca115ac0  0x3665fb5f1ac1
2   0x5212cb03ca115cc0  0x3665fb5f1ac7
3   0x5212cb03ca115ea0  0x3665fb5f1acd
4   0x5212cb03ca1160c0  0x3665fb5f1ad3
5   0x5212cb03ca1162a0  0x3665fb5f1ad9
6   0x5212cb03ca1164c0  0x3665fb5f1ade
7   0x5212cb03ca1166a0  0x3665fb5f1ae4
8   0x5212cb03ca1168a0  0x3665fb5f1aea
9   0x5212cb03ca116aa0  0x3665fb5f1af0
10  0x5212cb03ca116ca0  0x3665fb5f1af6
Run Code Online (Sandbox Code Playgroud)

命令:

awk  '{print $1 "  "strtonum($2)-0x5212cb03ca115ac0 "  "strtonum($3)-0x3665fb5f1ac1 }' output.txt
Run Code Online (Sandbox Code Playgroud)

我得到的输出如下.

1   0     0
2   1024  6
3   2048  12
4   2048  18
5   2048  24
6   3072  29
7   4096  35
8   4096  41
9   4096  47
10  5120  53
Run Code Online (Sandbox Code Playgroud)

如果你看到第2列中的值有一些重复的值(2048和4096).这是由于使用strtonum时精度损失引起的

有人可以建议一些方法来实现相同但避免这种精度损失.

ric*_*ici 5

值得注意的是,从版本4.1.0开始,如果您提供--bignum命令行标志(如果gawk是使用bignum支持编译的话),gawk支持bignums.不幸的是,debian/ubuntu打包器尚未赶上新版本(它于5月发布).

这是我在一个合理的股票ubuntu系统上安装gawk-4.1.0的方法:

# Download the source.
$ curl http://ftp.gnu.org/gnu/gawk/gawk-4.1.0.tar.gz > gawk-4.1.0.tar.gz
# Get the needed header files
$ sudo apt-get install libgmp-dev libmpfr-dev
# Unpack the gawk distribution
$ tar xf gawk-4.1.0.tar.gz
# Configure and compile it
$ ./configure
$ make
# Install it (as /usr/local/bin/gawk)
$ sudo make install

# Try it out
$ gawk --bignum '{printf "%2d %8d %8d\n",
                 $1, strtonum($2)-0x5212cb03ca115ac0,
                 strtonum($3)-0x3665fb5f1ac1 }' test.dat 
 1        0        0
 2      512        6
 3     1344       12
 4     1536       18
 5     2016       24
 6     2560       29
 7     3040       35
 8     3552       41
 9     4064       47
10     4576       53
Run Code Online (Sandbox Code Playgroud)

(实际上,这有点误导.我已经安装了gawk 4.1,但我假装我正在做新鲜事.而且,现在我想起来了,我使用的是.xz文件,而不是.gz文件,但是我确定他们两个都解压缩到同样的东西..xz版本只有一半.)