反向乘法

时间:2015-05-19 20:20:50

标签: java math biginteger modulus

我有以下号码;让我们称之为第一

  

-1757151608

然后我有第二个号码,我们称之为未知

  

94507795

最后,我有了产品,我们称之为第二号

  

-1000

如果我将表格中的前两个数字相乘,我的答案为-1000。 问题是,我有第一名和第二名,但我需要从中得到未知数。

我尝试过使用BigInteger类及其中一些函数而没有运气。

提前致谢。

2 个答案:

答案 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的常见因素之后“第一号”,你就不会得到任何答案。在那种情况下,没有答案。

如果在偶数情况下有答案,则答案不止一个。如果您运行我的程序,您会看到它与您的程序有不同的答案。

请检查一下,让我知道它是否按预期方式工作。