2009-09-15 43 views
8

我在尋找一個diff工具,它也可以比較文本文件中的浮點值(在一定的容差內)。這是除了典型的文本比較比較功能,以及忽略空白,忽略大小寫等選項。一個GUI(或全屏控制檯UI)是好的,但我真的更喜歡面向流(stdin /標準輸出)工具。Diff工具在文本中忽略浮點格式(但不包含值)?

下面是一個非常簡單的例子,描述了理想的工具。有2個版本的foo.c的:

foo_v1.c:

#include <stdio.h> 

#define PI  3.14159265359 
#define E_CUBED 20.0855 
#define HALF_PHI 0.809f 
#define C_SQUARED 89875517873681764.0L 

const double AVO = 6.022e23; /* Avocado number */ 

int main() 
{ 
    printf("%g %g %g %Lg %g\n", PI, E_CUBED, HALF_PHI, C_SQUARED, AVO); 
    return 0; 
} 

foo_v2.c:

#include <stdio.h> 

#define PI  3.14159265358979 
#define E_CUBED 2.00855e+1 
#define HALF_PHI 8.09e-1f 
#define C_SQUARED 8.9875517873681764e18L 

const double AVO = 6.022e23; /* Avogadro number */ 

int main() 
{ 
    printf("%g %g %g %Lg %g\n", PI, E_CUBED, HALF_PHI, C_SQUARED, AVO); 
    return 0; 
} 

而這裏的diff的輸出,我期望:

$ diff --floats=byvalue --tolerance=1e-9 foo_v1.c foo_v2.c 
6c6 
< #define C_SQUARED 89875517873681764.0L 
--- 
> #define C_SQUARED 8.9875517873681764e18L 
8c8 
< const double AVO = 6.022e23; /* Avocado number */ 
--- 
> const double AVO = 6.022e23; /* Avogadro number */ 

第二個差異(第8行)是通常的文本差異;第一個差異(第6行)是由於數字超出了指定的公差範圍。 (指數應該是16,而不是18,所以它的偏差是100.0X)。

請注意,即使它們是文本更改,其他浮點更改都不會顯示爲差異—,但浮點值不會超出指定的容差。

有沒有可以做到這一點的差異工具?

如果沒有,是否有東西接近,那是開源的?

回答

5

有這個,看起來很有趣。我試圖把它的工作對我的AIX,所以我還沒有它似乎在行動,但我相信這是你(和我:-)需要

http://hpux.connect.org.uk/hppd/hpux/Text/spiff-1.0/

+0

哇!輸出**完全**我想要的!順便說一句,BeOS版本[http://www.bebits.com/app/3784]在Cygwin下編譯,沒有任何變化。 – 2009-09-28 23:44:06

+0

那麼,我仍然無法在AIX上運行它。在Linux上,gcc-3.3.3編譯它,但是它在第一個「spiff Sample.1 Sample.2」上出現了segfault錯誤。在一臺較新的機器上,gcc-4.2.4很生氣: spiff.c:178:error:'_Y_doargs'的靜態聲明遵循非靜態聲明 spiff.c:30:錯誤:之前的'_Y_doargs'聲明爲這裏 – Davide 2009-09-29 16:05:53

+0

@Davide:如果你仍然陷入困境,也許你應該在某個網站的某個地方問一個關於它的問題。 ;-) – 2009-10-02 20:47:32

0

我不知道這樣的工具,但通過將一些奇特的浮點正則表達式集合與一組例程組合在一起以正常化所述正則浮點數,可以很容易地掀起一個Perl腳本來爲您做這件事。如果您需要幫助,我可能會對此感到震驚,但這是一個耗時的企業,所以我會成爲一隻貪婪的豬,並要求提供有用的獎勵。

+0

感謝您的報價。實際上,我一直在爲此編寫我自己的工具,但我不相信正則表達式足以在指定的容差範圍內進行比較。 – 2009-09-23 23:38:23

+0

如果你推出我們自己的,你想要做的就是使用Math :: library層次結構(Math :: BigFloat,我認爲)可能與你可以在CPAN上找到的最好的浮點正則表達式匹配,或者構建你自己 - Perl Regexp book有一些不錯的。如果你幸運的話,Math :: hierarchy有它自己的解析器(一段時間沒有用過,所以不記得)。 – DVK 2009-09-24 12:29:13

+0

正則表達式不能合理地計算公差。您需要將這些值轉換爲機器花車並進行比較。 – 2009-10-03 23:16:17

1

Smart Differencer Tools。這些工具根據程序結構比較兩個源代碼文件,而不是比較文本行。爲此,這些工具根據語言規則解析源文件,構建AST並比較樹。輸出依據程序結構(標識符,表達式,語句,塊,方法等)的抽象編輯更改(插入,刪除,移動,複製,重命名)。

作爲一種副作用,個別語言詞位(如字符,字符串和數字文字)會轉換爲正常形式的內部表示。文字的格式被忽略,所以它會將浮點值(如00.001和1e-03)視爲相同,0xFF和255相同,「\ n」和「\ u000a」等同。這不包括對浮點數的公差模糊,但它會忽略它的形狀。這意味着SmartDifference工具將報告兩個相應但略有不同的數字,但它只會報告數字;你會得到類似

<Line 75 col 15-19 1.01 
    >replace by Line 75 col 15-19 1.02 

的匹配目前允許標識符是不同的,把一個統一的標識符跨越範圍重命名爲一個編輯,而那一堆不同的修改。使用浮點模糊來允許近似未命中數字匹配的想法很有趣,我將它添加到可能的功能請求列表中。

這些工具是爲Java,COBOL和C#生產的。我們有C++和C的預生產版本;困難的問題是挑選語言的程序結構,通過使用宏和預處理器條件有效地允許任意編輯源代碼。

+0

絕對是我想要的方向邁出的一步,而且非常酷。我很好奇「內部表示」如何在沒有容差的情況下比較浮點值。我猜如果你受限於文字(而不是計算結果),容差並不是絕對必要的。但它不是一個漂亮的功能? ;-) – 2009-10-05 15:32:04

+0

@system暫停:比較「內部表示」很容易。取二進制浮點值,並相互比較是否相等。這與比較標識符或字符串文字沒有區別。 – 2009-10-05 15:37:10