2017-12-15 27 views
1

私は2つの関数を含むCファイルを使用しようとしています。その1つは変数のアドレスを引数として取る関数です"&"とその変数の値を変更します(少なくともこれは私が信じるものです))。"adress"を関数の引数として渡す - Python 3

int seed1; 
int seed2; 

rmarin_(seed1,seed2); 
float rand; 
ranmar1_(&rand); 

それで変数「ランド」の値は、いくつかのようになります。ここではCでの使用例は以下のようになり機能(彼らは一種の理解することが複雑である)

#define LEN 255 
static float u[97],c,cd,cm; 
static int i97,j97,ileft; 

ranmar1_(ran) 
float *ran; 
    { 
    register float uni, cint; 
    register float* listptr; 
    register int ivec,i97int,j97int; 
    static float rvec[LEN]; 
    if (ileft < 0) 
     { 
     i97int = i97; 
     j97int = j97; 
     cint = c; 
     for (ivec = 0; ivec <= LEN; ivec++) 
     { 
     uni = u[i97int] - u[j97int]; 
     if (uni < 0) uni++; 
     u[i97int--] = uni; 
     if (i97int < 0) i97int = 96; 
     j97int--; 
     if (j97int < 0) j97int = 96; 
     cint -= cd; 
     if (cint < 0.) cint += cm; 
     uni -= cint; 
     if (uni < 0.) uni++; 
     rvec[ivec] = uni; 
     } 
     ileft = LEN; 
     c = cint; 
     j97 = j97int; 
     i97 = i97int; 
     } 
    *ran = rvec[ileft--]; 
    } 
/*****************************************************************/ 
rmarin_(ij,kl) 
int ij,kl; 
    { 
    int i,j,k,l,m,ii,jj; 
    float s,t; 
    printf("%d\n",ij); 
    printf("%d\n",kl); 
    printf("*******************\n"); 
    i = ((ij/177) % 177) + 2; 
    j = (ij % 177) + 2; 
    k = ((kl/169) % 178) + 1; 
    l = kl % 169; 
    for (ii = 0; ii <= 96; ii++) 
     { 
     s = 0; 
     t = .5; 
     for (jj = 1; jj <= 24; jj++) 
     { 
     m = (((i*j) % 179)*k) % 179; 
     i = j; 
     j = k; 
     k = m; 
     l = (53*l +1) % 169; 
     if (((l*m) % 64) >= 32) s = s + t; 
     t = 0.5 * t; 
     } 
     u[ii] = s; 
     } 
    c = 362436./16777216.; 
    cd = 7654321./16777216.; 
    cm = 16777213./16777216.; 
    i97 = 96; 
    j97 = 32; 
    ileft=(-1); 
    } 
/*****************************************************************/ 

です0と1の間の擬似ランダム値。 私はこれらの関数をPythonで使用しようとしていますが、問題があります。私はを&xとして使用しています。なぜなら、私はそれが少なくとも関連していることが分かったからです。ここに私のコードはありますか?

私はまずCファイルを使って.soファイルを作成し、それをPython3で使用しています。問題は、xの値が変わらないことです。 xの値を0と1の間の擬似乱数に変更するにはどうすればよいですか?

+4

Cコードはどこにありますか?これらのANSI標準関数ヘッダーより前のものです。だけでなく、undechipherable。 –

+0

このコードを使用する必要はありますか?それを変更して、ポインタパラメータを介して変更する代わりに値を返すようにすることができます。 – Gerhardh

+0

私の教授が私に教えてくれて、Pythonでそれを使うように言った。このコードは、1989年にミシガン大学のByron Roeによって作成されました。 変更については正直言って私はそこで何が起こっているのかよく分かりません。私は恐らく、Cコードを持たずに、Pythonで良い解決策を見つけることは可能かもしれないと思いました。 –

答えて

3

Cコードの奇妙な性質を除いて、id(x)はPythonのアドレスではありません。これは、特定のオブジェクトに固有の識別子ですが、Pythonランタイムが望みどおりのものにすることができます。 Pythonの実装によっては、負の整数(明らかに有効なアドレスではありません)からIDを選択することは可能です。

標準実装CPythonでは、オブジェクトのアドレスをIDとして使用します。しかし、その場合でも、ポインタを必要とするctypes関数にそのアドレスを渡すことはできません。なぜなら、IDを作成するために使用されるアドレスはおそらく値を指していないからです。おそらく、Pythonの「ラッパー」オブジェクトのアドレスです。

私が意味
// earlier in the code 
struct PyInteger { 
    unsigned int reference_count; 
    int value; 
    // lots of other attributes 
}; 

// ... 
const PyInteger* value = PyInteger_from_cache(2); 
PySymbolTable* locals = local_symbol_table(stack_frame); 
PySymbolTable_set(locals, "x", value); 

、それはおそらくないとしても、すべてのものと同様の実際のコードではありませんし、たとえば、ときに舞台裏で何が起こるか

Pythonで
x = 2 

は、これらの線に沿って多少ある書き込み私はちょうど私の頭の上からこれを考え出しましたが、少なくとも変数に値を代入するよりもCレベルでもっと多くのことが起こっているという考えを与えるべきです。 id(x)をポインタとして使用しようとすると、このコード例では、PyIntegerオブジェクトのアドレスが取得されますが、C int値のアドレスは取得されません。

あなたがするべきことは、ctypes.byref()またはctypes.pointer()を使用して、C関数に渡すポインタを作成することです。そして、指し示されているオブジェクトは、例えば以下のインスタンスでなければならない。 ctypes.c_int、Pythonの整数ではありません。 Python整数は決して変更されないと考えられますが、c_intはその値を変更することができます。


ちなみに、乱数だけが必要な場合、Pythonには組み込み方法があります。

+0

私はctypes.byrefを使用しましたが、正常に動作しました。また、私は説明のために感謝したいと思います。変数を宣言するときに、 "ボンネットの下に"多くのことがあることは分かっていましたが、それが何であるか分かりませんでした。今はもっとはっきりしています。 ありがとうございます。 –

関連する問題