php 浮点数 gmp计算,C/C++ gmp库之浮点数实例

#include

#include

#include

#include

int main(){

// void mpf_set_default_prec(mp_bitcnt_t prec)

// 将默认精度设置为至少 prec 位。所有后续调用mpf_init将使用此精度,但先前初始化的变量不受影响。

// 这个值可以按需设置,比如计算毫秒级时间,

mpf_set_default_prec(64); // 默认精度,即小数点后精确多少位

/*

* 浮点数的结构体

typedef struct

{

int _mp_prec;// mp_limb_t 的最大精度。由 mpf_init 设置,

// 由 mpf_set_prec 修改。

// _mp_d字段指向的区域包含' prec' + 1个 limb(s)。

int _mp_size;// abs(_mp_size)是最后一个字段指向的 limb(s) 数。

// 如果 _mp_size 是负数,则这就是一个负数。

mp_exp_t _mp_exp; // 以 mp_limb_t 为底的指数。

mp_limb_t *_mp_d; // 指向 limb(s) 的指针。

} __mpf_struct;

* */

mpf_t a, b, c, d, e, f, g, h;

// 第一种初始化 + 赋值的方法

mpf_init(a); // 初始化变量 a

mpf_set_ui(a, 0); // 为 a 赋值,a=0

// 第二种初始化并同时赋值的方法

mpf_init_set_ui(b, 3); // 初始化 b,并把 3 赋值给它,即 b=3

mpf_init_set_ui(c, 5); // 初始化的值为无符号整数

mpf_init_set_ui(d, 7);

mpf_init_set_ui(e, 300);

int res = mpf_init_set_str(f, "8", 10); // 正确,则返回0; 错误,则返回-1

std::cout << "-- mpf_init_set_str() [0:正确,-1:错误] res= " << res << std::endl;

mpf_init_set_str(g, "19", 10); // 初始化的值为字符串

mpf_init_set_si(h, -10); // 初始化值为有符号的数

// mpf_init()的功能 + mpf_set()的功能 = mpf_init_set()的功能

// mpf_init()的功能 + mpf_set_ui()的功能 = mpf_init_set_ui()的功能

gmp_printf("-- a= %Ff, b= %Ff, c= %Ff, d= %Ff, e= %Ff, f= %Ff, g= %Ff\n", a, b, c, d, e, f, g); // 显示初始化的变量值

mpf_add(a, b, c); // 加法

gmp_printf("-- 加法(a=b+c):\t\t%Ff\n", a); // 默认保留 6 位小数

gmp_printf("-- 加法(a=b+c)[精度 2]:%.*Ff\n", 2, a);

mpf_add(a, b, f); // 加法

gmp_printf("-- 加法(a=b+f)[精度 2]:%.*Ff\n", 2, a);

mpf_add(a, c, f); // 加法

gmp_printf("-- 加法(a=c+f)[精度 2]:%.*Ff\n", 2, a);

mpf_add(a, g, f); // 加法

// 打印结构体元素

gmp_printf("-- 加法(a=g+f)[精度 2]:\t%.*Ff,\t_mp_prec= %d, _mp_size= %d, _mp_exp= %d, _mp_d= %d\n", 2, a, a->_mp_prec, a->_mp_size, a->_mp_exp, *a->_mp_d);

mpf_sub(a, b, c); // 减法

gmp_printf("-- 减法(a=b-c):\t\t%Ff\n", a); // 默认保留 6 位小数

// 打印结构体元素

gmp_printf("-- 减法(a=b-c)[精度 2]:\t%.*Ff,\t_mp_prec= %d, _mp_size= %d, _mp_exp= %d, _mp_d= %d\n", 2, a, a->_mp_prec, a->_mp_size, a->_mp_exp, *a->_mp_d);

mpf_mul(a, b, c); // 乘法

gmp_printf("-- 乘法(a=b*c):\t\t%Ff\n", a); // 默认保留 6 位小数

// 打印结构体元素

gmp_printf("-- 乘法(a=b*c)[精度 2]:\t%.*Ff,\t_mp_prec= %d, _mp_size= %d, _mp_exp= %d, _mp_d= %d\n", 2, a, a->_mp_prec, a->_mp_size, a->_mp_exp, *a->_mp_d);

mpf_div(a, b, d); // 除法

gmp_printf("-- 除法(a=b/d):\t\t%Ff\n", a); // 默认保留 6 位小数

gmp_printf("-- 除法(a=b/d)[精度 2]:\t%.*Ff\n", 2, a);

gmp_printf("-- 除法(a=b/d)[精度 9]:\t%.*Ff\n", 9, a);

// 打印结构体元素

gmp_printf("-- 除法(a=b/d)[精度 10]:%.*Ff,\t_mp_prec=%d, _mp_size=%d, _mp_exp=%d, _mp_d=%d\n", 10, a, a->_mp_prec, a->_mp_size, a->_mp_exp, *a->_mp_d);

/**

* gmp 数据转换为字符串

* char * mpf_get_str (char *str, mp_exp_t *expptr, int base, size_t n_digits, const mpf_t op)

* str: 如果为nullptr,则函数返回转换后的值;如果为非nullptr,则此变量保存转换后的值

* expptr: 小数点的下标位置,因为转换后的数字字符串是纯数字的。

* 即:如op=3.1415926,则expptr=1;如op=314.15926,则expptr=3;如op=0.314,则expptr=0

* base: 进制,范围:2..36,使用数字和小写字母;-2 ..- 36,使用数字和大写字母;

* 37..62,使用数字,大写字母和小写字母(按重要性顺序)

* n_digits:最多生成n_digits个数字。如果 n_digits为0,则将生成该准确的最大位数。

* 当n_digits为0以获取所有有效数字时,应用程序将无法知道所需的空间,

* 在这种情况下,str应该是nullptr

* op: 被转换的数据

*/

char *word; // 保存转换完的数据

int length; // 转换完的字符串长度

mp_exp_t exponent; // 保存结果字符串

word = mpf_get_str(nullptr, &exponent, 10, 0, a);

length = strlen(word);

printf("-- mpf_get_str(): word:\texponent= %ld, length= %d, word= %s\n", exponent, length, word);

mpf_div(a, e, d); // 除法

gmp_printf("-- 除法(a=e/d)[精度 10]:%.*Ff\n", 10, a);

word = mpf_get_str(nullptr, &exponent, 10, 0, a); // 把gmp数字转为字符串

length = strlen(word);

printf("-- mpf_get_str(): word:\texponent= %ld, length= %d, word= %s\n", exponent, length, word);

mpf_pow_ui(a, b, 3); // 幂

gmp_printf("-- 幂(a=b^3)[精度 2]:%.*Ff,\t_mp_prec=%d, _mp_size=%d, _mp_exp=%d, _mp_d=%d\n", 2, a, a->_mp_prec, a->_mp_size, a->_mp_exp, *a->_mp_d);

mpf_mul_2exp(a, b, 0); // a = b * 2^0

gmp_printf("-- 2exp(a=b* 2^0)[精度 2]:%.*Ff,\t_mp_prec=%d, _mp_size=%d, _mp_exp=%d, _mp_d=%d\n", 2, a, a->_mp_prec, a->_mp_size, a->_mp_exp, *a->_mp_d);

mpf_mul_2exp(a, b, 1);

gmp_printf("-- 2exp(a=b* 2^1)[精度 2]:%.*Ff,\t_mp_prec=%d, _mp_size=%d, _mp_exp=%d, _mp_d=%d\n", 2, a, a->_mp_prec, a->_mp_size, a->_mp_exp, *a->_mp_d);

mpf_mul_2exp(a, b, 2);

gmp_printf("-- 2exp(a=b* 2^2)[精度 2]:%.*Ff,\t_mp_prec=%d, _mp_size=%d, _mp_exp=%d, _mp_d=%d\n", 2, a, a->_mp_prec, a->_mp_size, a->_mp_exp, *a->_mp_d);

mpf_mul_2exp(a, b, 3);

gmp_printf("-- 2exp(a=b* 2^3)[精度 2]:%.*Ff,\t_mp_prec=%d, _mp_size=%d, _mp_exp=%d, _mp_d=%d\n", 2, a, a->_mp_prec, a->_mp_size, a->_mp_exp, *a->_mp_d);

// 把 b 的值赋给 a

mpf_set(a, b);

gmp_printf("-- 把 b 的值赋给 a, a:%.*Ff\n", 2, a);

// 取反,把 b 取反后的值赋给 a

mpf_neg(a, b);

gmp_printf("-- 取反,把 b 取反后的值赋给 a, a:%.*Ff\n", 2, a);

// 绝对值

mpf_abs(a, a);

gmp_printf("-- 绝对值,a:%.*Ff\n", 2, a);

// 转换 gmp 数据

unsigned int ui = mpf_get_ui(b); // gmp 数据转为 ui 类型数据

printf("-- mpf_get_ui(): b: unsigned int ui= %d\n", ui);

ui = mpf_get_ui(c); // gmp 数据转为 ui 类型数据

printf("-- mpf_get_ui(): c: unsigned int ui= %d\n", ui);

// double mpf_get_d_2exp(signed long int *exp, const mpf_t op)

// https://gmplib.org/manual/Converting-Floats

signed long int exp; // 保存精度

double d_2exp = mpf_get_d_2exp(&exp, a); // a = d_2exp * 2^exp, a = d_2exp * 2^3

gmp_printf("-- mpf_get_d_2exp(): a: %Ff, exp= %d, _mp_exp= %d, d_2exp= %f\n", a, exp, a->_mp_exp, d_2exp);

d_2exp = mpf_get_d_2exp(&exp, b);

gmp_printf("-- mpf_get_d_2exp(): b: %Ff, exp= %d, _mp_exp= %d, d_2exp= %f\n", b, exp, b->_mp_exp, d_2exp);

d_2exp = mpf_get_d_2exp(&exp, c);

gmp_printf("-- mpf_get_d_2exp(): c: %Ff, exp= %d, _mp_exp= %d, d_2exp= %f\n", c, exp, c->_mp_exp, d_2exp);

/* 输出:

-- mpf_init_set_str() [0:正确,-1:错误] res= 0

-- a= 0.000000, b= 3.000000, c= 5.000000, d= 7.000000, e= 300.000000, f= 8.000000, g= 19.000000

-- 加法(a=b+c): 8.000000

-- 加法(a=b+c)[精度 2]:8.00

-- 加法(a=b+f)[精度 2]:11.00

-- 加法(a=c+f)[精度 2]:13.00

-- 加法(a=g+f)[精度 2]: 27.00, _mp_prec= 2, _mp_size= 1, _mp_exp= 1, _mp_d= 27

-- 减法(a=b-c): -2.000000

-- 减法(a=b-c)[精度 2]: -2.00, _mp_prec= 2, _mp_size= -1, _mp_exp= 1, _mp_d= 2

-- 乘法(a=b*c): 15.000000

-- 乘法(a=b*c)[精度 2]: 15.00, _mp_prec= 2, _mp_size= 1, _mp_exp= 1, _mp_d= 15

-- 除法(a=b/d): 0.428571

-- 除法(a=b/d)[精度 2]: 0.43

-- 除法(a=b/d)[精度 9]: 0.428571429

-- 除法(a=b/d)[精度 10]:0.4285714286, _mp_prec=2, _mp_size=2, _mp_exp=0, _mp_d=1840700269

-- mpf_get_str(): word: exponent= 0, length= 21, word= 428571428571428571429

-- 除法(a=e/d)[精度 10]:42.8571428571

-- mpf_get_str(): word: exponent= 2, length= 21, word= 428571428571428571429

-- 幂(a=b^3)[精度 2]:27.00, _mp_prec=2, _mp_size=1, _mp_exp=1, _mp_d=27

-- 2exp(a=b* 2^0)[精度 2]:3.00, _mp_prec=2, _mp_size=1, _mp_exp=1, _mp_d=3

-- 2exp(a=b* 2^1)[精度 2]:6.00, _mp_prec=2, _mp_size=1, _mp_exp=1, _mp_d=6

-- 2exp(a=b* 2^2)[精度 2]:12.00, _mp_prec=2, _mp_size=1, _mp_exp=1, _mp_d=12

-- 2exp(a=b* 2^3)[精度 2]:24.00, _mp_prec=2, _mp_size=1, _mp_exp=1, _mp_d=24

-- 把 b 的值赋给 a, a:3.00

-- 取反,把 b 取反后的值赋给 a, a:-3.00

-- 绝对值,a:3.00

-- mpf_get_ui(): b: unsigned int ui= 3

-- mpf_get_ui(): c: unsigned int ui= 5

-- mpf_get_d_2exp(): a: 24.000000, exp= 5, _mp_exp= 1, d_2exp= 0.750000

-- mpf_get_d_2exp(): b: 3.000000, exp= 2, _mp_exp= 1, d_2exp= 0.750000

-- mpf_get_d_2exp(): c: 5.000000, exp= 3, _mp_exp= 1, d_2exp= 0.625000

-- 用时:16 ms

总结:

1、gmp_printf() 函数打印时如果不输入精度,则默认打印精度为6

2、通过 除法精度9 和 除法精度10 可以看出默认是有四舍五入的

3、通过 exponent=0 和 exponent=2,可以看出这是小数点的下标

*/

// 释放x占用的空间。完成所有mpf_t变量后,请确保为所有变量调用此函数 。

mpf_clear(a);

mpf_clear(b);

mpf_clear(c);

mpf_clear(d);

mpf_clear(e);

mpf_clear(f);

mpf_clear(g);

return 0;

}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值