2017-07-18 104 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源代码并更新了我的答案。 –