C#中的Mod:返回错误的值
好的,这是我的代码:C#中的Mod:返回错误的值,c#,math,encryption,rsa,C#,Math,Encryption,Rsa,好的,这是我的代码: int a, b, c, d; double v1, v2, v3, vf, val; a = 110; b = 13; c = 437; d = 61; v1 = Convert.ToDouble(a); v2 = Convert.ToDouble(b); v3 = Convert.ToDouble(d); v
int a, b, c, d;
double v1, v2, v3, vf, val;
a = 110;
b = 13;
c = 437;
d = 61;
v1 = Convert.ToDouble(a);
v2 = Convert.ToDouble(b);
v3 = Convert.ToDouble(d);
val = Math.Pow(v1, v2);
val = val % c;
Console.WriteLine("O valor do primeiro MOD é: {0}", val);
vf = Math.Pow(val, v3);
vf = vf % c;
Console.WriteLine("O valor final é: {0}", vf);
Console.ReadKey();
事情是这样的,如果我用计算器计算,我会得到这些结果:110^13=3452271243931000000000000
3452271243931000000000000%437=48
48^61=35951372914138399900210185557119E+102
35951372914138399900210185557119E+102%437=110
但是,使用我的代码可以得到以下结果: () 对于那些看不到图像的人,结果如下: val=337
vf=6无论是
110^13
还是48^61
都不能使用64位双精度精确表示。数据类型没有足够的精度来精确表示这些值。因为不能准确地表示操作数,所以实际执行的算术与要执行的算术不同。一旦无法表示原始操作数,就没有恢复的希望
您需要使用具有足够精度的类型。例如,.无论是
110^13
还是48^61
都不能使用64位双精度精确表示。数据类型没有足够的精度来精确表示这些值。因为不能准确地表示操作数,所以实际执行的算术与要执行的算术不同。一旦无法表示原始操作数,就没有恢复的希望
您需要使用具有足够精度的类型。例如,.Double对于您的案例来说远远不够精确。双倍是。您的值分别为26位和102位。无法表示的数字只会丢失,导致精度损失 您应该使用某种类型的bigint库:
- (来自.NET 4.0)
- (来自.NET 4.0)
110^13
这样的大数字不能准确地表示为双精度-它们会丢失很多有效数字
解决方案是使用可以表示非常大的整数的类型来计算它
下面是如何使用biginger
:
BigInteger a = new BigInteger(110);
BigInteger b = new BigInteger(13);
BigInteger c = new BigInteger(437);
BigInteger val = BigInteger.ModPow(a, b, c);
请注意,有一种特殊的方法,ModPow()
,它结合了幂和模的提升
还请注意,您可以使用隐式构造函数将int
转换为biginger
,从而将上述代码简化为:
BigInteger val = BigInteger.ModPow(110, 13, 437);
使用double不起作用的原因是double数据类型没有足够的精度。像
110^13
这样的大数字不能准确地表示为双精度-它们会丢失很多有效数字
解决方案是使用可以表示非常大的整数的类型来计算它
下面是如何使用biginger
:
BigInteger a = new BigInteger(110);
BigInteger b = new BigInteger(13);
BigInteger c = new BigInteger(437);
BigInteger val = BigInteger.ModPow(a, b, c);
请注意,有一种特殊的方法,ModPow()
,它结合了幂和模的提升
还请注意,您可以使用隐式构造函数将int
转换为biginger
,从而将上述代码简化为:
BigInteger val = BigInteger.ModPow(110, 13, 437);
你需要使用一个大数字库来存储这么大的数字。你需要使用一个大数字库来存储这么大的数字。谢谢,这很有帮助,但我还是被卡住了。我用的是2008版,现在用的是Visual Studio 2010 Ultimate。我以NET Framework 4.0为目标启动了一个新项目,并添加了System.Numerics引用(解决方案资源管理器>右键单击>添加引用>System.NET>System.Numerics),但出现错误“错误1无法找到类型或命名空间名称“BigInteger”(是否缺少using指令或程序集引用?)。感谢您的支持。经过更详细的观察后,我发现我漏掉了“使用System.Numerics;”这句话@Matthew你的答案并不能解释任何事情。它没有解释问题中的代码为什么不起作用。@DavidHeffernan I补充了更多的解释。我真的希望你的答案会被标记出来,我只是添加了一些代码来帮助这项工作。@Matthew谢谢。我想asker很感激为他们充实代码。谢谢,这很有帮助,但我还是被卡住了。我用的是2008版,现在用的是Visual Studio 2010 Ultimate。我以NET Framework 4.0为目标启动了一个新项目,并添加了System.Numerics引用(解决方案资源管理器>右键单击>添加引用>System.NET>System.Numerics),但出现错误“错误1无法找到类型或命名空间名称“BigInteger”(是否缺少using指令或程序集引用?)。感谢您的支持。经过更详细的观察后,我发现我漏掉了“使用System.Numerics;”这句话@Matthew你的答案并不能解释任何事情。它没有解释问题中的代码为什么不起作用。@DavidHeffernan I补充了更多的解释。我真的希望你的答案会被标记出来,我只是添加了一些代码来帮助这项工作。@Matthew谢谢。我想asker很感激为他们充实代码。