2013-08-27 2 views
2

У меня есть текстовый файл в следующем формате.strtonum in 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 

Команда:

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

Вывод, который я получаю приведен ниже.

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 

Если вы видите значения в колонке 2 имеет несколько значений повторяясь. (2048 и 4096) .Это вызвано из-за потери точности при использовании StrToNum

Может кто-то предложить какой-либо метод для достижения но избегайте этой потери точности.

+0

Я думаю, это потому, что числа представлены внутри как плавающая точка, которая содержит только 54 бит мантиссы. – Barmar

+1

Можете ли вы использовать perl вместо awk? Вы можете включить там бигнамы и получить произвольные числа точности. – Barmar

+0

@Barmar уверен, что я могу использовать perl вместо awk, если вы можете сказать мне, как :) – liv2hak

ответ

2

Возможно, это может получить работу:

awk '{print $1 " "strtonum("0x"substr($2,11))-0xca115ac0 " "strtonum($3)-0x3665fb5f1ac1 }' input 

и версия Perl:

perl -lane '{print join(" ", $F[0], hex($F[1])-0x5212cb03ca115ac0, hex($F[2]) - 0x3665fb5f1ac1)}' input 
+0

Набор данных на самом деле больше 5000. Я только что разместил 10 строк текстового файла здесь. Он может быть больше 11.for пример. – liv2hak

+0

добавил код Perl, но все же, возможно, '' 0x "substr ($ 2,5)) - 0x12cb03ca115ac0' достаточно? – perreal

1

Вы можете использовать bc. Это не может быть именно то, что вам нужно, но я уверен, что вы можете Твик, чтобы получить желаемый результат ...

$ cat bc_output.txt 
obase=10 
ibase=16 
5212CB03CA115AC0 - 5212CB03CA115AC0 ; 3665FB5F1AC1 - 3665FB5F1AC1 
5212CB03CA115CC0 - 5212CB03CA115AC0 ; 3665FB5F1AC7 - 3665FB5F1AC1 
5212CB03CA115EA0 - 5212CB03CA115AC0 ; 3665FB5F1ACD - 3665FB5F1AC1 
5212CB03CA1160C0 - 5212CB03CA115AC0 ; 3665FB5F1AD3 - 3665FB5F1AC1 
5212CB03CA1162A0 - 5212CB03CA115AC0 ; 3665FB5F1AD9 - 3665FB5F1AC1 
5212CB03CA1164C0 - 5212CB03CA115AC0 ; 3665FB5F1ADE - 3665FB5F1AC1 
5212CB03CA1166A0 - 5212CB03CA115AC0 ; 3665FB5F1AE4 - 3665FB5F1AC1 
5212CB03CA1168A0 - 5212CB03CA115AC0 ; 3665FB5F1AEA - 3665FB5F1AC1 
5212CB03CA116AA0 - 5212CB03CA115AC0 ; 3665FB5F1AF0 - 3665FB5F1AC1 
5212CB03CA116CA0 - 5212CB03CA115AC0 ; 3665FB5F1AF6 - 3665FB5F1AC1 
quit 

$ bc -l bc_output.txt 
bc 1.06 
Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc. 
This is free software with ABSOLUTELY NO WARRANTY. 
For details type `warranty'. 
0 
0 
512 
6 
992 
12 
1536 
18 
2016 
24 
2560 
29 
3040 
35 
3552 
41 
4064 
47 
4576 
53 
5

Стоит отметить, что в версии 4.1.0, простак поддерживает bignums если вы предоставить - bignum флаг командной строки (и если gawk был скомпилирован с поддержкой bignum). К сожалению, пакеты debian/ubuntu еще не догоняли новую версию (она была выпущена в мае).

Вот что я сделал, чтобы установить Gawk-4.1.0 на системе достаточно складе Ubuntu:

# 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 

(На самом деле, это немного вводит в заблуждение, я уже поглазеть 4,1 установлен, но я сделал вид, что я был. делая это свежо. Кроме того, теперь, когда я думаю об этом, я использовал файл .xz, а не файл .gz, но я уверен, что оба они декомпрессируются в одно и то же. Версия .xz в два раза меньше.)

Смежные вопросы