php 的一元二次方程_php扩展 求解一元二次方程

[TOC]

### 第一步 生成扩展demo Runing起来

#### 生成扩展demo

> 我们以php-7.4.1版本为例。

进入 cd php-7.4.1/ext 此目录,有一个名为 ext_skel.php。我们用此脚本生在扩展demo步骤如下

```

./ext_skel.php --ext gwalker

```

这样就在 ext目录下生成 gwalker扩展目录,目录内容如下:

```

[root@gw gwalker]# ls

config.m4 config.w32 gwalker.c php_gwalker.h tests

```

接下来进行编译,安装到php扩展中

```

[root@gw gwalker]# phpize

Configuring for:

PHP Api Version: 20131106

Zend Module Api No: 20131226

Zend Extension Api No: 220131226

```

```

./configure --with-php-config=/data/php/bin/php-config

make && make install

```

```

修改php.ini 把生成的so加关联到扩展中去

extension=/data/php/lib/php/extensions/debug-non-zts-20190902/gwalker.so

```

这样就把gwalker扩展加到php环境中去了。可以通过cli命令验证查看

```

./php -m | grep gwalker

gwalker

```

也可以重新启动php-fpm(或php内置web服务),通过浏览器验证

```

函数功能如下:

>求解 a*x^2 + b*x +c = 0;

>如果a为0则降级为一元一次方程求解。否则有无解的话返回布尔false,一个解返回数组[x],两个解返回数组[x1,x2]

#### 编码求解函数 getSolutionOVQE

> 注 OVQE 为Quadratic equation of one variable

```c

PHP_FUNCTION(getSolutionOVQE)

{

double a = 0;

double b = 0;

double c = 0;

// 定义x1,x2用来保放一元二次方程的两个解

double x1 = 0;

double x2 = 0;

// detal 记录 b^2 - 4ac的值

double detal = 0;

// =========参数接收处理阶段 begin ===============

ZEND_PARSE_PARAMETERS_START(2, 3) //接收参数,最少两个参数,最多3个参数

Z_PARAM_DOUBLE(a) // 接收第一参数,赋a

Z_PARAM_DOUBLE(b) // 接收第二参数,赋b

Z_PARAM_OPTIONAL // 表示后面的参数为选填项

Z_PARAM_DOUBLE(c) // 接收第二参数,赋c

ZEND_PARSE_PARAMETERS_END();

// =========参数接收处理阶段 end ===============

// 如果a与b两个系统数都为0,则返回false

if (a == 0 && b == 0)

{

RETURN_FALSE;

}

// 扩展开发通过return_value这个变量设置方法的返回值

array_init(return_value);

// 如果a=0 ,则降级为一元一次方程求解

if (a == 0)

{

x1 = -1 * (c/b);

add_index_double(return_value, 0, x1);

return;

}

detal = pow(b, 2) - 4 * a * c;

if (detal == 0)

{

x1 = (-b + sqrt(detal)) / (2 * a);

add_index_double(return_value, 0, x1);

return;

}

else if (detal > 0)

{

x1 = (-b + sqrt(detal)) / (2 * a);

x2 = (-b - sqrt(detal)) / (2 * a);

add_index_double(return_value, 0, x1);

add_index_double(return_value, 1, x2);

return;

}

// 都不符合是返回false

RETURN_FALSE;

}

```

##### 注册 getSolutionOVQE 函数

```c

static const zend_function_entry gwalker_functions[] = {

PHP_FE(gwalker_test1, arginfo_gwalker_test1)

PHP_FE(gwalker_test2, arginfo_gwalker_test2)

PHP_FE(getSolutionOVQE, NULL)

PHP_FE_END

};

```

#### 重新编译,测试

```

make && make install

```

```php

';

var_dump($v);

$h = getSolutionOVQE(1,2,1);

var_dump($h);

$h = getSolutionOVQE(1,-7,12);

var_dump($h);

$h = getSolutionOVQE(5,7,1);

var_dump($h);

$h = getSolutionOVQE(0,0,0);

var_dump($h);

$h = getSolutionOVQE(2,1,20);

var_dump($h);

$h = getSolutionOVQE(90,100,25);

var_dump($h);

$h = getSolutionOVQE(0,100,25);

var_dump($h);

exit;

```

输出如下:

```

array(1) {

[0]=>

float(-2)

}

array(1) {

[0]=>

float(-1)

}

array(2) {

[0]=>

float(4)

[1]=>

float(3)

}

array(2) {

[0]=>

float(-0.16148351928655)

[1]=>

float(-1.2385164807135)

}

bool(false)

bool(false)

array(2) {

[0]=>

float(-0.37987346332398)

[1]=>

float(-0.73123764778713)

}

array(1) {

[0]=>

float(-0.25)

}

```

#### 附php代码版求一元二次方程

```php

function php_getSolutionOVQE($a,$b,$c=0){

$x1=0;

$x2=0;

$detal=0;

if($a==0 && $b==0){

return false;

}

if($a==0){

$x1 = -1 * ($c/$b);

return [$x1];

}

$detal = pow($b,2) - 4*$a*$c;

if($detal == 0){

$x1 = (-1*$b + sqrt($detal)) / (2 * $a);

return [$x1];

}else if($detal > 0){

$x1 = (-1*$b + sqrt($detal)) / (2 * $a);

$x2 = (-1*$b - sqrt($detal)) / (2 * $a);

return [$x1,$x2];

}

return false;

}

```

#### 性能比较

现在分别进行100万次的一元二次方程求解。看下所用耗时

c扩展版如下(执行5次,用时记录如下):

```

use time : 0.993971824646 s

use time : 0.99442791938782 s

use time : 0.99134087562561 s

use time : 0.99235987663269 s

use time : 0.99243712425232 s

```

php代码版如下(执行5次,用时记录如下):

```

use time : 2.2686109542847 s

use time : 2.2673828601837 s

use time : 2.2710490226746 s

use time : 2.3082909584045 s

use time : 2.2692041397095 s

```

观察结果性能提升了2.2倍

**性能测试代码如下:**

> c扩展版

```

';

for($i = 1;$i<=1000000;$i++){

$a = $i+2;

$b = $i*3;

$c = $i+6;

$re = getSolutionOVQE($a,$b,$c);

//var_dump($re);

}

$end_time = microtime(true);

echo 'use time : '.($end_time-$start_time).' s';

exit;

```

> php代码版

```php

0){

$x1 = (-1*$b + sqrt($detal)) / (2 * $a);

$x2 = (-1*$b - sqrt($detal)) / (2 * $a);

return [$x1,$x2];

}

return false;

}

$start_time = microtime(true);

echo '';

for($i = 1;$i<=1000000;$i++){

$a = $i+2;

$b = $i*3;

$c = $i+6;

$re = php_getSolutionOVQE($a,$b,$c);

//var_dump($re);

}

$end_time = microtime(true);

echo 'use time : '.($end_time-$start_time).' s';

exit;

```

#### 代码地址

[https://github.com/gongwalker/getSolutionOVQE](https://github.com/gongwalker/getSolutionOVQE)

你可能感兴趣的:(php,的一元二次方程)