繁体   English   中英

ac 函数的错误输出返回从 python 调用的双精度

[英]Wrong ouptut of a c function returning a double called from python

我想加快调用 ac 函数的 python 代码:

我在 vanilla python sum_and_multiply.py中有一个函数:

def sam_py(lim_sup):
  total = 0
  for i in range(0,lim_sup): # xrange is slower according 
    for j in range(1, lim_sup):            #to my test but more memory-friendly.
      total += (i / j)
  return total

然后我在 C sum_and_multiply_c.c中具有等效功能:

#include <stdio.h>


double sam_c(int lim_sup){
  int i;
  int j;
  double total;
  total = 0;
  double div;
  for (i=0; i<lim_sup; i++){
    for (j=1; j<lim_sup; j++){

      div = (double) i / j;
//      printf("div: %.2f\n", div);
      total += div;
 //     printf("total: %.2f\n", total);
    }
  }
  printf("total: %.2f\n", total);
  return total;
}

调用 2 个函数的文件script.py

from sum_and_multiply import sam_py
import time

lim_sup = 6000

start = time.time()
print(sam_py(lim_sup))
end = time.time()
time_elapsed01 = end - start
print("time elapsed: %.4fs" % time_elapsed01)

from ctypes import *
my_c_fun = CDLL("sum_and_multiply_c.so")
start = time.time()
print(my_c_fun.sam_c(lim_sup))
end = time.time()
time_elapsed02 = end - start
print("time elapsed: %.4fs" % time_elapsed02)
print("Speedup coefficient: %.2fx" % (time_elapsed01/time_elapsed02))

最后是一个 shell 脚本bashscript.zsh ,它编译 C 代码然后调用script.py

cc -fPIC -shared -o sum_and_multiply_c.so sum_and_multiply_c.c
python script.py

这是输出:

166951817.45311993
time elapsed: 2.3095s
total: 166951817.45
20
time elapsed: 0.3016s
Speedup coefficient: 7.66x

这是我的问题,尽管 c 函数正确计算了结果(通过 printf 输出 166951817.45),但它在传递给 python 时的输出是 20,这是错误的。 我怎么能有 166951817.45 呢?

修改script.py最后部分后问题依旧,如下:

from ctypes import *
my_c_fun = CDLL("sum_and_multiply_c.so")
my_c_fun.restype = c_double
my_c_fun.argtypes = [ c_int ]
start = time.time()
print(my_c_fun.sam_c(lim_sup))
end = time.time()
time_elapsed02 = end - start
print("time elapsed: %.4fs" % time_elapsed02)
print("Speedup coefficient: %.2fx" % (time_elapsed01/time_elapsed02))

您假设 Python 可以“看到”您的函数返回一个double 但它不能。 C 不会在任何内容中“编码”返回类型,因此从库中调用函数的任何人都需要知道它的返回类型,否则就有误解它的风险。

在使用它之前,您应该阅读CDLL的文档! 如果您说这是为了锻炼,那么锻炼需要包括阅读文档(这是优秀程序员所做的,没有任何借口)。

 class ctypes.CDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False)

此类的实例表示已加载的共享库。 这些库中的函数使用标准 C 调用约定,并假定返回int

(强调我的。)

https://docs.python.org/2.7/library/ctypes.html#return-types是你的朋友(页面顶部会告诉你 Python2 已经死了,你不应该使用它,即使你坚持我相信你有比 Python 开发者自己更好的理由!)。

my_c_fun = CDLL("sum_and_multiply_c.so")
sam_c = my_c_fun.sam_c
sam_c.restype = c_double
sam_c.argtypes = [ c_int ]
value = sam_c(6000)
print(value)

是要走的路。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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