![](/img/trans.png)
[英]Why does blowfish code written in php give different results in Python?
[英]Python code from C code does not give the same results
我有用于纸张的 C 代码。 我想在 Python 中编写确切的代码。
这是所需的一切:
C 代码中使用的主要 function 是:
#include "mrand_seeds.h"
#define norm 2.328306549295728e-10 /* 1.0/(m1+1) */
#define norm2 2.328318825240738e-10 /* 1.0/(m2+1) */
#define m1 4294967087.0
#define m2 4294944443.0
double mrand(int stream)
{
long k;
double p,
s10 = drng[stream][0], s11 = drng[stream][1], s12 = drng[stream][2],
s20 = drng[stream][3], s21 = drng[stream][4], s22 = drng[stream][5];
p = 1403580.0 * s11 - 810728.0 * s10;
k = p / m1; p -= k*m1; if (p < 0.0) p += m1;
s10 = s11; s11 = s12; s12 = p;
p = 527612.0 * s22 - 1370589.0 * s20;
k = p / m2; p -= k*m2; if (p < 0.0) p += m2;
s20 = s21; s21 = s22; s22 = p;
drng[stream][0] = s10; drng[stream][1] = s11; drng[stream][2] = s12;
drng[stream][3] = s20; drng[stream][4] = s21; drng[stream][5] = s22;
if (s12 <= s22) return ((s12 - s22 + m1) * norm);
else return ((s12 - s22) * norm);
}
drng
是mrand_seeds.h
中 60000 个整数的列表:(下面的列表不是文件中的完整列表)
static double drng[][6] =
{
0, 0, 1, 0, 0, 1,
1772212344, 1374954571, 2377447708, 540628578, 1843308759, 549575061,
2602294560, 1764491502, 3872775590, 4089362440, 2683806282, 437563332,
376810349, 1545165407, 3443838735, 3650079346, 1898051052, 2606578666,
1847817841, 3038743716, 2014183350, 2883836363, 3242147124, 1955620878,
1075987441, 3468627582, 2694529948, 368150488, 2026479331, 2067041056,
134547324, 4246812979, 1700384422, 2358888058, 83616724, 3045736624,
2816844169, 885735878, 1824365395, 2629582008, 3405363962, 1835381773,
675808621, 434584068, 4021752986, 3831444678, 4193349505, 2833414845,
2876117643, 1466108979, 163986545, 1530526354, 68578399, 1111539974,
411040508, 544377427, 2887694751, 702892456, 758163486, 2462939166};
现在我在 Python 中写了mrand
function:
M1 = 4294967087
M2 = 4294944443
NORM1 = 2.328306549295728e-10
NORM2 = 2.328318825240738e-10
def mrand(stream):
s10 = drng1[stream][0]
s11 = drng1[stream][1]
s12 = drng1[stream][2]
s20 = drng1[stream][3]
s21 = drng1[stream][4]
s22 = drng1[stream][5]
p = 1403580.0 * s11 - 810728.0 * s10
k = p / M1
p -= k * M1
if p < 0:
p += M1
s10 = s11
s11 = s12
s12 = p
p = 527612.0 * s22 - 1370589.0 * s20
k = p / M2
p -= k*M2
if p < 0.0:
p += M2
s20 = s21
s21 = s22
s22 = p
drng1[stream][0] = s10
drng1[stream][1] = s11
drng1[stream][2] = s12
drng1[stream][3] = s20
drng1[stream][4] = s21
drng1[stream][5] = s22
if s12 <= s22 :
return ((s12 - s22 + M1) * NORM1)
else:
return ((s12 - s22) * NORM1)
并在另一个.py
文件中定义列表并导入 Python 代码并将其转换为二维数组。
import myfunc
drng = myfunc.retlist()
drng1 = [drng[i:i+6] for i in range(0, len(drng), 6)]
rtlist
function 简单地定义列表并返回它。
Now my problem is when I'm executing C code I get different output with different parameter but in Python I always get 0.9999999997671695
is output even with different parameter.
我究竟做错了什么?
在 C 代码中, k
变量被声明为整数类型,因此以下代码序列充当一种fmod
操作,将除法后的余数留在p
中:
k = p / M1; // Here, k will be TRUNCATED to the integral part of the division
p -= k * M1; // So re-multiplying and then subtracting will leave the remainder
因此,给定p
和M1
的初始值分别为9.0
和7.0
,在这两行代码之后, p
将为2.0
。
但是,在您的 Python 代码中, k
变量将是浮点类型,除法将是“精确的”,并且p
的值(假设p
和M1
的起始值与上述相同)在除法后将为零-乘减运算序列:
p = 9.0
M1 = 7.0
k = p / M1 # k here is NOT an integer ...
p -= k * M1 # ... so this will reduce p to zero
print(p)
实际上,当k
与p
和M1
具有相同(实数)类型时,在这两行代码之后p
将始终(非常接近)为零(并且使用k = p / M2;
操作重复该问题)。
可能有多种方法可以解决此问题(我不是 Python 专家),但一个简单的解决方案是将除法的结果转换为 integer:
k = int(p / M1)
p -= k * M1
或者,实现相同结果的一种可能更“Pythonic”的方法是使用地板除法运算符( //
):
k = p // M1 # Floor division - returns the integral part of the quotient
p -= k * M1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.