Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C#中将BigInteger转换为pow Double?_C#_Math_Biginteger - Fatal编程技术网

如何在C#中将BigInteger转换为pow Double?

如何在C#中将BigInteger转换为pow Double?,c#,math,biginteger,C#,Math,Biginteger,我尝试使用biginger.Pow方法来计算10^12345.987654321之类的值,但此方法仅接受整数作为指数,如下所示: Pow(大整数x,整数y) 那么,如何在上述方法中使用双倍数作为指数?在C#中不支持任意精度的大数,因此无法直接实现。有一些替代方案(比如寻找第三方库),或者您可以尝试下面的代码——如果库足够小,比如您的情况 public class StackOverflow_11179289 { public static void Test() {

我尝试使用
biginger.Pow
方法来计算10^12345.987654321之类的值,但此方法仅接受整数作为指数,如下所示:

Pow(大整数x,整数y)


那么,如何在上述方法中使用双倍数作为指数?

在C#中不支持任意精度的大数,因此无法直接实现。有一些替代方案(比如寻找第三方库),或者您可以尝试下面的代码——如果库足够小,比如您的情况

public class StackOverflow_11179289
{
    public static void Test()
    {
        int @base = 10;
        double exp = 12345.123;
        int intExp = (int)Math.Floor(exp);
        double fracExp = exp - intExp;
        BigInteger temp = BigInteger.Pow(@base, intExp);
        double temp2 = Math.Pow(@base, fracExp);
        int fractionBitsForDouble = 52;
        for (int i = 0; i < fractionBitsForDouble; i++)
        {
            temp = BigInteger.Divide(temp, 2);
            temp2 *= 2;
        }

        BigInteger result = BigInteger.Multiply(temp, (BigInteger)temp2);

        Console.WriteLine(result);
    }
}
我们可以将这两个值合并成一个大整数。但是简单地将double值转换为BigInteger会损失很多精度,因此我们首先将精度“移位”到BigInteger上(使用上面的循环,以及
double
类型使用52位精度的事实),然后将结果相乘

请注意,结果是近似值,如果需要更精确的数字,则需要一个执行任意精度浮点运算的库


更新:如果基/指数足够小,幂在
double
的范围内,我们可以简单地按照塞巴斯蒂安·皮尤的建议(
新的大整数(Math.Pow((double)@base,exp))

我喜欢卡洛斯·菲盖拉的答案,但当然他的方法的结果只能在第一步是正确的(最高有效)15-17位,因为
系统.Double
最终用作乘法器

值得注意的是,确实存在一种执行“逆”运算的方法
biginger.Log
。因此,如果您想计算
Pow(7123456.78)
理论上,您可以搜索所有
biginger
numbers
x
以找到一个
biginger.Log(x,7)的数字
等于
123456.78
或比
biginger
类型的任何其他
x
更接近
123456.78

当然,对数函数在增加,因此您的搜索可以使用某种“二进制搜索”(对分搜索)。我们的答案介于
Pow(7123456)
Pow(7123457)
之间,两者都可以精确计算

如果需要,请跳过其余部分

现在,我们如何提前预测是否有一个以上的整数的对数是
123456.78
,达到
System.Double
的精度,或者实际上没有一个整数的对数达到特定的
Double
(理想的
Pow
函数的精确结果是无理数)?在我们的示例中,会有很多整数给出相同的
Double
123456.78
,因为因子
m=Pow(7,ε)
(其中,
epsilon
是最小的正数,
123456.78+epilon
表示为
Double
,不同于
123456.78
本身的表示)足够大,以至于真实答案和真实答案乘以
m
之间会有很多整数

从微积分中记住,数学函数的导数
x→ 功率(7,x)
is
x→ Log(7)*Pow(7,x)
,因此所讨论的指数函数图的斜率将是
Log(7)*Pow(7123456.78)
。这个数字乘以上面的
epsilon
仍然远远大于1,因此有许多整数满足了我们的需要


实际上,我认为carlosfigueira的方法将给出一个“正确”的答案
x
,即
Log(x,7)
123456.78
具有相同的
Double
表示。但是有人尝试过吗?:-)我将提供另一个希望更清楚的答案。重点是:因为
系统的精度。Double
被限制为大约15-17位小数,这是任何
Pow(biginger,Double)的结果
计算的精度将更加有限。
因此,没有希望比carlosfigueira的答案做得更好

让我用一个例子来说明这一点。假设我们想要计算

Pow(10, exponent)
在本例中,我选择双精度数字作为指数

const double exponent = 100.0 * Math.PI;
这当然只是一个例子。
指数
(十进制)的值可以作为

314.159265358979
314.15926535897933
314.1592653589793258106510620564222335815429687500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000...
这些数字中的第一个是您通常看到的数字(15位)。第二个版本是使用exponent.ToString(“R”)生成的,包含17位数字。请注意,
Double
的精度小于17位。上面的第三个表示是理论上的“精确”
指数的值
。请注意,这当然与第17位附近的数学数字100π不同

为了弄清楚Pow(10,指数)应该是什么,我简单地对许多数字
x
进行了
biginger.Log10(x)
,以了解如何重现
index
。因此,这里给出的结果只是反映了.NET框架对
biginger.Log10
的实现

结果是,任何
biginger x
都来自

0x0C3F859904635FC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
through
0x0C3F85990481FE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
使
Log10(x)
等于
指数
,精度为15位。类似地,从

0x0C3F8599047BDEC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
through
0x0C3F8599047D667FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
满足
Log10(x)=指数
Double
的精度。换句话说,后一个范围内的任何数字作为
Pow(10,指数)
的结果都是同样“正确”的,因为
指数
的精度非常有限

(插曲:
0
s和
F
s表明.NET的实现只考虑了
x
中最重要的字节。他们不想做得更好,正是因为
Double
类型的精度有限。)

现在,引入第三方的唯一原因
0x0C3F8599047BDEC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
through
0x0C3F8599047D667FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF