2017-07-18 152 views
0

我正在將一個算法從C移植到Go。我有點困惑。這是C函數:C long long golang

void gauss_gen_cdf(uint64_t cdf[], long double sigma, int n) 
{ 
    int i; 
    long double s, d, e; 

    //Calculations ... 

    for (i = 1; i < n - 1; i++) { 
     cdf[i] = s; 
    } 
} 

而在for循環值「s」被分配給元素「x」數組cdf。這怎麼可能?據我所知,一個long double是float64(在Go上下文中)。所以我不應該能夠編譯C代碼,因爲我給一個只包含uint64元素的數組分配了一個long double。但是C代碼工作正常。

那麼有人可以解釋爲什麼這是行得通的嗎?

非常感謝。

UPDATE:

函數的C原碼可以在這裏找到:https://github.com/mjosaarinen/hilabliss/blob/master/distribution.c#L22

+0

即使在C中,你的代碼也沒有意義,可能有一些[未定義的行爲](https://en.wikipedia.org/wiki/Undefined_behavior )。因此,改進C代碼以使其符合標準。 –

+0

爲什麼不在Go中使用現有的高斯分佈實現(例如[go-gaussian](https://github.com/chobie/go-gaussian/)),而不是再次移植C代碼(並且引入了自己的代碼錯誤)? – dolmen

回答

0

分配cdf[i] = s執行隱式轉換到uint64_t。沒有你省略的計算,很難說這是否是有意的。

實際上,long double作爲一種類型在不同架構之間有很大差異。 Go的float64是否是一個合適的替代品取決於您從中移植的架構。例如,在x86上,long double是一個80字節的擴展精度類型,但Windows systems are usually configured in such a way to compute results only with the 53-bit mantissa,這意味着float64仍然可以等同於您的目的。

編輯在這種特殊情況下,由源計算的值看起來是靜態的並且與輸入無關。我將在Go側使用float64,並查看在真實GNU/Linux(虛擬化應該是否正常)下運行在x86計算機上時,計算出的值是否與C版本相同,以解決Windows FPU問題。 x86的選擇只是一種猜測,因爲它可能是原作者所使用的。我不明白底層密碼學,所以我不能說計算值的差異是否會影響安全性。 (另請注意,C代碼似乎沒有正確地種下它的PRNG。)

+0

我更新了問題,並添加了一個鏈接到原始源代碼。感謝您對不同架構的解釋。 –

+0

謝謝,我簡要介紹了一下C源代碼並更新了我的答案。 –