繁体   English   中英

C 代码中的 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);
}

drngmrand_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

因此,给定pM1的初始值分别为9.07.0 ,在这两行代码之后, p将为2.0

但是,在您的 Python 代码中, k变量将是浮点类型,除法将是“精确的”,并且p的值(假设pM1的起始值与上述相同)在除法后将为零-乘减运算序列:

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)

实际上,当kpM1具有相同(实数)类型时,在这两行代码之后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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM