我有以下号码;让我们称之为第一
-1757151608
然后我有第二个号码,我们称之为未知
94507795
最后,我有了产品,我们称之为第二号
-1000
如果我将表格中的前两个数字相乘,我的答案为-1000。 问题是,我有第一名和第二名,但我需要从中得到未知数。
我尝试过使用BigInteger
类及其中一些函数而没有运气。
提前致谢。
答案 0 :(得分:3)
无法扭转这种乘法。
首先,让我们取第一个数字的两个补码。
3904635256 = 2147483648 - -1757151608
接下来,我们将乘以第二个数字
369018468323820520 = 3904635256 * 94507795
现在,这是一个棘手的部分。我们将产品转换为十六进制,并丢弃大于32位整数的数字。
51F0457800003E8 (hex) = 369018468323820520 (decimal)
800003E8 = 51F0457800003E8 moved to a 32 bit signed integer
现在,我们将十六进制值转换回十进制值
2147484648 (dec) = 800003E8 (hex)
最后,我们采用小数的两位补码
-1000 = 2147483648 - 2147484648
由于我们扔掉了51F0457 (hex)
,我们无法将其归还。这种操作的反向是不可能的。
答案 1 :(得分:1)
我相信你想要的是将-1000乘以-1757151608模2 ^ 32的乘法逆;例如,见the calculation in Wolfram Alpha。
我编写了一个程序,我相信当你的问题存在时,我会正确计算出你的问题的答案。
public class InverseMultiplication {
// multiplicative inverse of a multiplied by b mod 2^32
public static long invertAndMultiply(long a, long b) {
// take out common factors of 2
while (a % 2 == 0 && b % 2 == 0) {
a /= 2;
b /= 2;
}
long m = 256L*256L*256L*256L; // modulus is 2^32
long r = m;
long nr = a;
long t = 0;
long nt = 1;
while (nr != 0) {
long q = r/nr;
long tmp;
tmp = nt; nt = t - q*nt; t = tmp;
tmp = nr; nr = r - q*nr; r = tmp;
}
if (r > 1) throw new IllegalArgumentException(a + " has no inverse");
t = (t*b) % m;
while (t < Integer.MIN_VALUE) t += m;
while (t > Integer.MAX_VALUE) t -= m;
return t;
}
public static void main(String[] args) {
long twoPow32 = 256L*256L*256L*256L;
int n1 = -1757151608;
int n2 = -1000;
long unk = invertAndMultiply(n1,n2);
System.out.println(unk);
long pro = n1 * unk % twoPow32;
if (pro > Integer.MAX_VALUE) pro -= twoPow32;
System.out.println(pro);
int pro1 = -1757151608 * 94507795;
System.out.println(pro1);
}
}
然而,有几点需要注意。如果你的“头号”是奇数,那么程序会很快找到一个独特的答案。
偶数“头号”不会有逆模2 ^ 32,因此一般情况下你会失败。但是,如果你的“二号”也是偶数,你可以将两者除以2(“取公因子为2”),直到其中一个或两个都是奇数。希望“头号”很奇怪,在这种情况下你会得到答案;如果在取出所有2的常见因素之后“第一号”,你就不会得到任何答案。在那种情况下,没有答案。
如果在偶数情况下有答案,则答案不止一个。如果您运行我的程序,您会看到它与您的程序有不同的答案。
请检查一下,让我知道它是否按预期方式工作。