C 具有无符号长的Pow精度

C 具有无符号长的Pow精度,c,precision,pow,C,Precision,Pow,所以我试着做pow(x,y)。其中x和y为无符号长字符,结果存储在无符号长字符中。这个结果将小于2^63,所以我应该能够做到这一点。 但是因为它返回一个浮点数,所以对于大的数字,我得到的结果是不准确的。在不使用像bignum这样的外部库的情况下,是否仍然可以得到准确的结果? 我知道我可以简单地执行x*x a Y次,但这正是我试图避免的,因为我试图使我的程序更快。pow函数返回一个有精度问题的双精度函数,当您将其转换为long时,您肯定会遇到精度问题。据我所知,如果您不使用库,那么仅使用pow函数

所以我试着做pow(x,y)。其中x和y为无符号长字符,结果存储在无符号长字符中。这个结果将小于2^63,所以我应该能够做到这一点。 但是因为它返回一个浮点数,所以对于大的数字,我得到的结果是不准确的。在不使用像bignum这样的外部库的情况下,是否仍然可以得到准确的结果?
我知道我可以简单地执行x*x a Y次,但这正是我试图避免的,因为我试图使我的程序更快。

pow函数返回一个有精度问题的双精度函数,当您将其转换为long时,您肯定会遇到精度问题。据我所知,如果您不使用库,那么仅使用pow函数是不可能得到准确的结果的

你也可以看看,也可以看看巴拉克马诺斯,在那里你可以尝试实现你自己的战俘功能


根据定义,
pow
是不准确的。它使用
exp(y*log(x))
作为模拟
x^y
的方法。如果您想要完全精确,您需要使用外部库或制作自己版本的
pow

我不确定您的代码。但我猜你的代码是这样的

unsigned long x,y;
x=...//
y=...//

unsigned long res=pow(x,y);
这是不对的。因为pow()总是返回双精度类型

double pow(double x, double y) 
这就是为什么你有两个号码

要获得正确的号码,您可以执行以下操作:

    unsigned long x,y;
    x=...//
    y=...//

    unsigned long res=(unsigned long)pow(x,y);

你的密码在哪里?您可能需要将浮点值舍入到最接近的整数。
pow
确实是
exp(y*log(x))
,这很快,但存在精度问题。您可能对此感兴趣:我的问题是它不是1个数字不准确,而是37个。答案=功率(a,b);我没有标记为重复,因为你一开始不知道怎么做,但你可以看看这个:这个方法对非常大的数字有效吗?比如10000^10000(x^y)?因为我希望始终将值保持在2^63-1以下。因此,我正在尝试尽可能接近2^63-1,然后我将对该部分进行计算,将结果带入下一次计算,直到y变得足够小,可以立即进行计算。@LifeisHard:
10000^10000
不小于
2^63
,因此您可能会有其他问题。除了需要(大约)125个其他宇宙来存储所有这些数字之外,@Jongware:
10000^10000
大于2^63,但仍然可以很容易地放在网页上,尽管不是在注释中:a
1
后跟40000
0
s。@chqrlie:<根据谷歌的计算器,code>10000^10是
1e+40
。这是10 Gb–对于网页来说有点大–并且讨论中的数字要大一点。创建一个函数
unsigned long-long-pow(unsigned long x,unsigned int y).
是导致一些严重错误的好方法。C没有同名函数的签名。屏蔽/隐藏符合标准的`双倍功率(double,double);函数。这并不能解决OP的问题:“因为它返回一个浮点数,所以对于大数,我得到的结果不准确”。@Jongware您确定res的值是浮点数。您的解释令人困惑:只要通过
正确声明了
pow
,第一个选项就没有问题,到
unsigned long
的转换是隐式的,编译器将生成正确的代码。相反,如果未声明
pow
,则添加显式转换不会改变任何内容:编译器将假定函数具有
intpow(int,int)原型,生成的代码将完全错误。
    unsigned long x,y;
    x=...//
    y=...//

    unsigned long res=(unsigned long)pow(x,y);