我想实现我自己的(简单)大/任意整数精度算术,首先是在Java中(因为我对语法比较熟悉),然后将其重写为C.
我对无限长度的数字进行加法,减法和乘法,现在我需要模数用于加密应用程序。
我将任意数字的数字存储在数组中,我按照以下指南来说明如何存储数字: How to handle very large numbers in Java without using java.math.BigInteger
所以例如我想计算
849465603662254214335539562 % 578907659710377778063722
当我有两个数组时:
int[] a = [8, 4, 9, 4, 6, 5, 6, 0, 3, 6, 6, 2, 2, 5, 4, 2, 1, 4, 3, 3, 5, 5, 3, 9, 5, 6, 2]
int[] b = [5, 7, 8, 9, 0, 7, 6, 5, 9, 7, 1, 0, 3, 7, 7, 7, 7, 8, 0, 6, 3, 7, 2, 2]
代表这些数字。
获得
的简单解决方案是什么int[] c = modFunction(a, b)
感谢任何帮助。
答案 0 :(得分:1)
我想出了这个方法;它不一定有效,但它有效。
请注意,您可以使用输入的长度(以数字形式)来计算其对数。
您可以使用它来执行除法,因此也可以使用模数。
具体来说,首先注意
849465603662254214335539562 / (578907659710377778063722 * 1000) = 1.4...
因此
849465603662254214335539562 - 578907659710377778063722 * 1000 = 270557943951876436271817562
现在注意到
270557943951876436271817562 / (578907659710377778063722 * 100) = 4.6...
因此
270557943951876436271817562 - (578907659710377778063722 * 400) = 38994880067725325046328762
现在注意到
38994880067725325046328762 / (578907659710377778063722 * 10) = 6.7...
因此
38994880067725325046328762 - (578907659710377778063722 * 60) = 4260420485102658362505442
最后,请注意
4260420485102658362505442 / (578907659710377778063722 * 1) = 7.3...
因此
4260420485102658362505442 - (578907659710377778063722 * 7) = 208066867130013916059388
答案是208066867130013916059388
。
只需通过检查长度就可以轻松获得10的幂数,你可以通过乘法计算所有10种可能性并找出哪一个是非负的,可以计算出你需要减去哪一个。结果
只需使用乘法二元搜索商!然后使用商来找到余数。
答案 1 :(得分:1)
计算D mod M
时,您可以从D
中减去M
的任意整数倍,而不会更改结果。如果使用商D/M
的近似值减去,则可以更接近所需的模数。重复直到商0
会给你答案。
while D >= M
Q= some integer approximation of D / M
D= D - Q.M
要得到这样的商近似值,请取K
D
和M
的最高有效数字,并计算Q=10^K.D/M
的整数部分。这可以使用双精度算术方便地完成,并为您提供K
个数字(最多可以使用K=15
)。在减法之前添加len(D)-len(M)-K
个零进行重新排列。
请注意,在K
和D
(至M
个数字的近似值)之后,在K
数字后截断会导致商数出现小错误。 (我的猜测是Q
上的最大误差是一个单位。)这个错误并不重要,因为只要你减去M
的整数倍,D
仍然是确切的价值。最后,您需要检查0<=D<M
。
在给定的示例849465603662254214335539562 mod 578907659710377778063722
中,近似商为10^15.849465603662254 / 578907659710377 = 1467359412876373.
,您需要添加-12
个零(!)进行重新排列,即将小数点移到左侧并使用1467
。
然后849465603662254214335539562 - 1467 * 578907659710377778063722 = 208066867130013916059388
是请求的模数。
答案 2 :(得分:0)
Modulo非常简单:
a % b = a - floor((a / b)) * b
你需要的只是整数除法(或一个floor()和一个除法),乘法,减法。我想你已经有了这些操作。
如果只有整数,则不需要floor()
函数:
a % b = a - (a / b) * b
示例:
849465603662254214335539562 % 578907659710377778063722 =
849465603662254214335539562 - (849465603662254214335539562 / 578907659710377778063722) * 578907659710377778063722 =
849465603662254214335539562 - 1467 * 578907659710377778063722 =
849465603662254214335539562 - 849257536795124200419480174 =
208066867130013916059388
答案 3 :(得分:-2)
为什么你不想使用BigDecimal类?它具有remainder方法,可以完全按照您的要求进行操作。您可以查看source code of BigDecimal class以查看其实施方式。