1 / BigInteger in c#
我要实现
BigInteger.ModPow(1/BigInteger, 2,5);
但是1/BigInteger
总是返回0
,这导致结果为0
。 我试图为c#寻找一些BigDecimal
类,但我什么都没发现。 即使没有BigDecimal
有没有办法计算这个?
1/a
对于| a |> 1是0,因为BigIntegers
使用整数除法,其中忽略除法的小数部分。 我不确定你对此有什么期望。
我假设您想要模m
a
模乘法逆 ,而不是分数。 如果a
和m
是共素,即gcd(a, m) = 1
则存在该逆。
链接的维基百科页面列出了用于计算模乘法逆的两种标准算法:
-
扩展的欧几里德算法 ,适用于任意模量
它很快,但具有依赖于输入的运行时。我手头没有C#代码,但是从维基百科移植伪代码应该是直截了当的。
-
使用欧拉定理:
这需要知道φ(m),即你需要知道m的素因子。 当m
是素数时它是一种流行的选择,因此当它变成时,φ(m)= m-1 。 如果你需要恒定的运行时间,你知道φ(m),这就是你要走的路。在C#中,这变为
BigInteger.ModPow(a, phiOfM-1, m)
选择的/
运算符的重载如下:
public static BigInteger operator /( BigInteger dividend, BigInteger divisor )
请参阅BigInteger.Division运算符 。 如果结果在0
和1
之间(这可能是在你的情况下dividend
为1
),因为返回值是一个整数,如你所见,返回0
。
你想用ModPow
方法做什么? 你是否意识到2,5
是两个参数,两个和五个,而不是“两点五”? 你的意图是“取模5”吗?
如果你想要浮点除法,你可以使用:
1.0 / (double)yourBigInt
注意演员要double
。 如果你的yourBigInt
太大,这可能会失去精确度甚至“下溢”为零。
例如,您需要在下一个中获得:
3 * d = 1(mod 9167368)
这同样是:
3 * d = 1 + k * 9167368,其中k = 1,2,3,……
重写它:
d =(1 + k * 9167368)/ 3
你的d必须是k 最低的整数。
让我们写下公式:
d =(1 + k * fi)/ e
public static int MultiplicativeInverse(int e, int fi) { double result; int k = 1; while (true) { result = (1 + (k * fi)) / (double) e; if ((Math.Round(result, 5) % 1) == 0) //integer { return (int)result; } else { k++; } } }
让我们测试一下这段代码:
Assert.AreEqual(Helper.MultiplicativeInverse(3, 9167368), 6111579); // passed