/相 发表于 2024-4-7 07:08:02

关于128比特的指数、对数运算的实现

C++里面的double和long double只有$64$和$80$比特的精度,

但是我对精度的需求比较高,至少需要$128$比特的精度,

其中$1$比特用来表示正负号,$15$比特用来表示量级,其余$112$比特用来记录数据。

想问一下各位坛友,这样的浮点数的自然对数、自然指数是否已经实现?

如果是的话,能否拿到源代码?

如果还没实现,我将亲自出马,解决我自己的需求。

有了这两个函数,$x^y$运算就可以实现了:

$x^y=e^{y*ln(x)}$

参考文献$1$:

https://blog.csdn.net/qq_34030789/article/details/51476292

Sherryufas 发表于 2024-4-7 07:09:02

用gmp的mpf_t如何?

ejiwueu 发表于 2024-4-7 07:09:46

参考文献$2$:

————————————————————
急问:gmp高精度库浮点数使用问题 [问题点数:40分]

请问,gmp中的gmf_t高精度浮点数计算有问题?

比如:3.14/5.789

gmp结果:0.5424080152012437381240283295906

windows自带计算器和Java中的大数处理函数计算出来是:0.5424080152012437381240283295906

gmp从小数点后17位就不准了

这是怎么回事,gmp不是号称最好的高精度库吗?怎么一个浮点数除都不准啊!

#####

是我贴错了

请问,gmp中的gmf_t高精度浮点数计算有问题

比如:3.14/5.789

gmp结果:0.5424080152012437875651563769429

windows自带计算器和Java中的大数处理函数计算出来是:0.5424080152012437381240283295906

gmp从小数点后17位就不准了

这是怎么回事,gmp不是号称最好的高精度库吗?怎么一个浮点数除都不准啊!

是否是使用mpf_set_d去对gmf_t赋值的?这个会影响两个输入数据的精度。

看以下代码:
#include <stdlib.h>#include <stdio.h>#include "gmp.h"#define USE_STR 1int main(){mpf_t a, b, res;mpf_init2(a, 256);mpf_init2(b, 256);mpf_init2(res, 256);#if USE_STRmpf_set_str(a, "3.14", 10);mpf_set_str(b, "5.789", 10);#elsempf_set_d(a, 3.14);mpf_set_d(b, 5.789);#endifmpf_div(res, a, b);gmp_printf ("%.*Ff/%.*Ff", 50, a, 50, b);gmp_printf ("=%.*Ff\n", 50, res);mpf_clear(a);mpf_clear(b);mpf_clear(res);return 0;}
当USE_STR=1时,输出结果如下:

3.14000000000000000000000000000000000000000000000000
/
5.78900000000000000000000000000000000000000000000000
=
0.54240801520124373812402832959060286750734150975989

当USE_STR=0时,输出结果如下:

3.14000000000000012434497875801753252744674682617188
/
5.78899999999999970157205098075792193412780761718750
=
0.54240801520124378756515637694292549171967387220245
————————————————————

gocehuzana 发表于 2024-4-7 07:10:17

看来是舍入误差的问题了
mpf_set_d(a, 3.14)
这句话损失了精度
因为浮点数3.14代表的是一个分数
5.789同理
用python的Fraction库可以把这个分数读出来:
>>> Fraction(3.14)
Fraction(7070651414971679, 2251799813685248)
>>> Fraction(5.789)
Fraction(3258917280355975, 562949953421312)
于是你用double计算的3.14/5.789其实是用的
Fraction(7070651414971679, 2251799813685248)/Fraction(3258917280355975, 562949953421312)
约分结果是
Fraction(7070651414971679, 13035669121423900)
用pari/GP计算这个分数,得到:
0.54240801520124378756515637694292549172
前几位跟你写的一致

icakeekohude 发表于 2024-4-7 07:11:08

这个是因为double精度只有14位左右。mpf_set_d的输入参数类型是double,而计算机表达数值采用二进制,对于无法用二进制标识为有限小数的数值,在计算机里面用double表示是有误差的,而这个转化这里是c编译器做的,gmp毫无办法改善。如果我们换成二进制表示有限的小数比如0.375,那么就不会有精度问题了
页: [1]
查看完整版本: 关于128比特的指数、对数运算的实现