【问题标题】:Python code from C code does not give the same results来自 C 代码的 Python 代码不会给出相同的结果
【发布时间】:2021-08-23 06:46:58
【问题描述】:

我有用于论文的 C 代码。我想用 Python 编写确切的代码。

这里有所有需要的:

C 代码中使用的主要函数是:

#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 函数:

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 函数只定义了列表并返回它。

现在我的问题是,当我执行 C 代码时,我得到不同参数的不同输出,但在 Python 中,即使使用不同的参数,我总是得到 0.9999999997671695 的输出。

我做错了什么?

【问题讨论】:

  • 为什么不简单地逐步调试它,直到发现 Python 中的变量 state 与 C 中的变量不匹配,以便调查导致这种差异的原因?
  • 实际上,我这样做了,但是由于我已经有 5 或 6 年没有使用 C 或 C++ 了,所以我不知道如何通过库调试代码,因为所有这些事情都发生在图书馆。我正在寻找如何做到这一点,但答案很好,解决了我的问题。

标签: python c


【解决方案1】:

在 C 代码中,k 变量被声明为整数类型,因此以下代码序列充当fmod operation 的一种,在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

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

但是,在您的 Python 代码中,k 变量将是浮点类型,除法将是“精确”,p 的值(假设 p 和 @987654336 的起始值相同@ 如上)在除-乘-减运算序列之后将是

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)

事实上,当kp 和@987654341 具有相同(真实)类型时,p 在这两行代码之后将总是为零@ (k = p / M2; 操作会重复此问题)。


可能有多种方法可以解决这个问题(我不是 Python 专家),但一个简单的解决方案是将除法的结果转换为整数:

k = int(p / M1)
p -= k * M1

或者,实现相同结果的一种可能更“Pythonic”的方法是使用floor division operator (//):

k = p // M1 # Floor division - returns the integral part of the quotient 
p -= k * M1

【讨论】:

    猜你喜欢
    • 2020-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多