以双NUmber模数为例

时间:2016-04-08 06:47:40

标签: java algorithm module double precision

我已经给出了两个数字ab。我必须计算(a^b)%1000000007。如何计算浮点数。例如:

a= 7.654 and b=10000

以下是我的代码将%工作:

 public static double super_pow(double A , long B){

          double o=1;

          while(B>0){

              if((B&1)!=0) o*=A;

              A*=A;
              B/=2;
              o%=mod;
              A%=mod;
          }

          return (o)%mod;
    }

3 个答案:

答案 0 :(得分:1)

是的,在Java中,您可以在浮点类型上使用%运算符。

您将遇到指数问题:您无法使用%来减少中间结果,因为模数不会通过浮点乘法进行分布:(a*b)%c不是(a%c)*(b%c)。如果您尝试直接计算7.654 ^ 10000,您将获得infinity;它超过了double的最大值。即使它不是你也不能相信结果的最低位数,因为它们是由舍入和表示错误产生的纯噪声。

您可以使用实现精确算术的库,例如java.math.BigDecimal,但这会在执行时间和内存方面花费很多。如果你认为你需要将这个计算作为一个更大问题的一部分,那么你可能应该退后一步,找到另一种方法。

修改:以下是BigDecimal的结果:

BigDecimal[] divmod = new BigDecimal("7.654").pow(10000)
                             .divideAndRemainder(new BigDecimal("1000000007"))

return divmod[1].doubleValue() // I get 9.01287592373194E8

答案 1 :(得分:1)

在java中,你可以使用浮点数/双精度的模数运算(How do I use modulus for float/double?

如果您必须计算(a ^ b)%1000000007 ,则可以double使用abbiggest integer that can be stored in a double),这使取幂变得更容易,使用pow()方法(http://www.tutorialspoint.com/java/number_pow.htm

  import static java.lang.Math.pow;

  public static double super_pow(double A , double B){ //returns long and B is also double

      double pow;
      double mod = 1000000007.0;

      pow = Math.pow(A,B);
      mod = pow % 1000000007;
      return mod;
}

或者您可以将 a ^ b 的结果强制转换(精度损失!)到long,然后使用

double pow = Math.pow(A,B);
long mod = (long) pow%1000000007L; // the 'L' is important see https://stackoverflow.com/questions/5737616/what-is-the-modulo-operator-for-longs-in-java
return mod; //return a long not double in function

What is the modulo operator for longs in Java?

答案 2 :(得分:0)

%模数

这取决于您使用的语言。但通常浮点值不知道模运算。您可以自己计算它。假设正浮点数a=7.654b=10000.0如此

d = a/b = 0.0007654                               // division
r = d-floor(d) = (0.0007654-0.0) = 0.0007654      // remainder
r = r*b = (0.0007654*10000.0) = 7.654             // rescale back
  • floor(x)向下舍入到最接近x
  • 的数字
  • d持有浮动除法结果
  • r保留余数(模数)

另一个示例a=123.456b=65

d = a/b = 1.8993230769230769230769230769231
r = (d-floor(d))*b = 58.456

这可以用于a,b的整数和十进制值,但要注意浮点单元执行舍入,并且可以在几位数之后松开精度...如果我没记错,通常会有64位double变量最多可使用18位数。

[编辑1]嗯,你把这个问题重新编写成完全不同的问题

所以你正在搜索modpow。你可以谷歌实现modpow的java实现。例如这里

你可以在32位整数算术中用C ++找到我的实现,但是使用具有特定属性的静态模数。如果你改变所有

仍然
if (DWORD(d)>=DWORD(p)) d-=p;

d=d%p;它适用于任何模数。你需要modpow,modmul,modadd,modsub