swoole / phpy

Connecting the Python and PHP ecosystems together
Apache License 2.0
538 stars 44 forks source link

PY 整数如何执行除法 #49

Closed Dmcz closed 5 months ago

Dmcz commented 5 months ago

根据文档推测除法函数为div,但是这里会抛出异常,PHP Fatal error: Uncaught PyError: 'int' object has no attribute '__div__'

PyCore::int(2)->__div__(2); 

此外还有一个问题:如果需要大量的计算时,使用bcmath性能更好还是使用python的整数更优。

另外PY整数能支持链式调用就好啦,例如: PyCore::int(2)->__add__(1)->__mul__(2);

Dmcz commented 5 months ago

关于效率,我将numpy与bcmath 做了个简单的对比

// 示例代码
$min = 1;
$max = 100000000;

$arr = [];
for ($i=0; $i < 100000; $i++) { 
    $arr[] =  $min + mt_rand() / mt_getrandmax() * ($max - $min);
}    

$np = PyCore::import("numpy");

function mul(float $a, float $b): float{
    return (float) bcmul((string)$a, (string)$b, 10);
}

var_dump(microtime(true));
foreach($arr as $index => $item){
    $a = mul($item, $index);
}
var_dump(microtime(true));
foreach($arr as $index => $item){
    $a = $np->multiply($item, $index);
}
var_dump(microtime(true));

// 输出
// float(1715827413.047093)
// float(1715827413.135797)
// float(1715827413.299653)

var_dump(microtime(true));

$arr = range(0, 99999);

var_dump(microtime(true));

$list = $np->arange(0, 100000, 1);

var_dump(microtime(true));

$arr = array_map(function($n) { return (float) bcmul((string) $n, '21855.12345236', 10); }, $arr);

var_dump(microtime(true));

$np->multiply($list, 21855.12345236);

var_dump(microtime(true));

// 输出 float(1715827680.609606) float(1715827680.610147) float(1715827680.610507) float(1715827680.663684) float(1715827680.664193)

matyhtf commented 5 months ago

python 和 phpy 的操作是完全等价的,这个方法 python 代码一样不能运行

python
Python 3.11.5 (main, Sep 11 2023, 13:54:46) [GCC 11.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> a = 123
>>> a.__div__(2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute '__div__'. Did you mean: '__dir__'?

正确的写法是:

PyCore::int(2)->__truediv__(2); 

或者

PyCore::int(2)->__floordiv__(2); 

执行结果:

php -r "var_dump(PyCore::int(2)->__truediv__(2));"
float(1)
matyhtf commented 5 months ago

关于链式写法,我们考虑下,看看如何支持

PyCore::int(2)->__add__(1)->__mul__(2); 
Dmcz commented 5 months ago

ok. 可能我那天拼写错了,我试过__floordiv__不行, 抱歉。

matyhtf commented 5 months ago

已支持将 数字作为对象返回

PyCore::setOptions(['numeric_as_object' => true]);
$rs = PyCore::int(2)->__add__(3)->__mul__(7);
Dmcz commented 5 months ago

已支持将 数字作为对象返回

PyCore::setOptions(['numeric_as_object' => true]);
$rs = PyCore::int(2)->__add__(3)->__mul__(7);

ok,thx.