Link to home
Start Free TrialLog in
Avatar of yongeng
yongeng

asked on

Problem applying modulus(%) to a BigInteger

Hi All,

Can anyone help me with a work around?



double y1 = (Math.pow(x1, x2)) % x3;

where x1, x2 are integers and x3 is a BigInteger


Thanxs
Garion
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

Try

% x3.doubleValue();
Avatar of mightyone
mightyone

double y1 = (Math.pow(x1, x2)) % (double)x3;

or

double y1 =(double)(((BigInteger) (Math.pow(x1, x2))) % x3);



mightyone,
that results twice in
  inconvertible types

You can't cast a double to a BigInteger and vice versa
double y1 = (Math.pow(x1, x2)) % x3;

where x1, x2 are integers and x3 is a BigInteger

double y1 = Math.pow(x1, x2) % x3.longValue();
// or x3.intValue(); if you know the number can be stored in an int.
You will have to make the assumption that the BigInteger value holds something which is not greater than the range of long and optimistically use longValue (). Though I don't think that this would help in your case (if it was a value within the range of long that you wanted to store, why would you use a BigInteger in the first place?).

By the way, you might be better of converting the result of Math.pow () into a BigInteger and using the remainder () method provided by the BigInteger class.
SOLUTION
Avatar of Mayank S
Mayank S
Flag of India image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I assumed that x3 BigInteger was given to him (argument or someting like that).
If x3 may hold values bigger then long (which actually I doubt that is the case for a module value) then Yes you can take
the approach of using only BigInteger calculation.
somethig like that:
BigInteger result = new BigInteger(x1).modPow(new BigInteger(x2). x3);
you can always call result.longValue() or result.intValue()
mayankeagle, I think remainder works differently then mod when it comes to negative values.
>> I think remainder works differently then mod when it comes to negative values.

Does it? Not sure as I never tried it. But anyway, why should it? Anyway, I hope that is not the case here :)

>> If x3 may hold values bigger then long (which actually I doubt that is the case for a module value)

In that case, why to make a BigInteger after all :) just store it as a 'long'. yongeng, what is the case?
Avatar of yongeng

ASKER

>> In that case, why to make a BigInteger after all :) just store it as a 'long'. yongeng, what is the case?

Hi mayankeagle,

would there a difference stroing my integer as long?

the value input would be a very large value.....

how do I declare it as a long interger?

Thanxs
Garion
Yes, there is difference:
From java sources:
reminder -> divide(this, val, null, rem, TRUNCATE);
mod -> divide(this, m, null, rem, FLOOR);

and the rounding logic:
switch (rounding_mode)
703     {
704     case TRUNCATE:
705       break;
706     case CEILING:
707     case FLOOR:
708       if (qNegative == (rounding_mode == FLOOR))
709         add_one = true;
710       break;
711     case ROUND:
712       add_one = r > ((y - (q & 1)) >> 1);
713       break;
714     }

Also, because such operation of pow and mod is so common (RSA,...) they have one method for it as I meantioned "modPow"
I think you should go all the way with BigInteger so you will not have any "trancation" problems.
>> would there a difference stroing my integer as long?

Why are you using a BigInteger in the first place? Perhaps because the values are very large?

>> how do I declare it as a long interger?

long x3 ; // just like any other variable-declaration - but do that only if you know that the value will fit in it

>> the value input would be a very large value

If it is bigger than a 'long', then you should use BigInteger the way you are using. And if it will always be a positive value, then you could use the remainder () method as I had shown.
mayankeagle, man you are living on the edge ;-)
Good night.
I was talking about the reminder thing (if you didn't get my joke) no offend :-)
Avatar of yongeng

ASKER

>>BigInteger bigInt = new BigInteger ( Long.toString ( Math.pow ( x1, x2 ) ) ) ;
>>BigInteger remainder = bigInt.remainder ( x3 ) ;
>>int r = remainder.intValue () ; // or long r = remainder.longValue () ;

Hi mayankeagle,

Can you explain this? I dun realli understand how it works.....

When I run it, i got an error for line 1.... saying "cannot resolve symbol
symbol  : method toString (double)"
Avatar of yongeng

ASKER

>>BigInteger result = new BigInteger(x1).modPow(new BigInteger(x2). x3);

When I tried this, it compiles with the same error.....
Try: BigInteger bigInt = new BigInteger ( Double.toString ( Math.pow ( x1, x2 ) ) ) ;
Avatar of yongeng

ASKER

>> Try: BigInteger bigInt = new BigInteger ( Double.toString ( Math.pow ( x1, x2 ) ) ) ;


thanxs....

it compiles with no errors now, but when i run it with the test values, it terminates with an error.....
What is the error that it gives? Please post your updated code.
Right, sorry BigInteger doesn't accept integer in the constuctor (but does accept string).
See that:
import java.math.*;

public class Tmp
{
public static void main(String st[]) throws Exception
{
int x1 = 12;
int x2 = 2;
BigInteger x3 = new BigInteger("5");
BigInteger result = new BigInteger(String.valueOf(x1)).modPow(new BigInteger(String.valueOf(x2)), x3);
System.out.println(result);
}
}

output:
knoppix@ttyp1[knoppix]$ javac Tmp.java
knoppix@ttyp1[knoppix]$ java Tmp
4
Avatar of yongeng

ASKER

Hi mayankeagle,

The error is "Exception in thread "main" java.lang.NumberFormat Exception: For inout string: "Infinity" ........"

my updated code is:
BigInteger bigInt = new BigInteger ( Double.toString ( Math.pow ( x1, x2 ) ) ) ;
BigInteger remainder = bigInt.remainder ( x3 ) ;
int r = remainder.intValue () ; // or long r = remainder.longValue () ;


thanxs
Avatar of yongeng

ASKER

Hi aozarov,

I tried to change the codes to yours but after running with the test values, the result is always 0....
Avatar of yongeng

ASKER

>> I tried to change the codes to yours but after running with the test values, the result is always 0....

sorrie aozarov, i mixed up the values.... it working now :)
:-)
Avatar of yongeng

ASKER

hi aozorov,

can you roughly explain how it the statement works?

espacially the modPow....
x.modPow(y,z) is doing exactly: (x ^ y) % z
or in words: (x power y) mod z.
It is added to the JDK because it is a common thing to do in cryptography.
If you look at BigInteger API you see many other related methods (like isPrime ....)
Avatar of yongeng

ASKER

thanxs aozarov..... you have been a great help :)


would like to consult you on one last question on this topic.....

I tried to modify your statement to calculate   ((x ^ y)*a) % z
 but I was prompted with the error that "operator * cannot be applied to bigInteger".... is there a work around?
Yes. Use BigIntger       multiply(BigInteger val)  function.

chage:
BigInteger result = new BigInteger(String.valueOf(x1)).modPow(new BigInteger(String.valueOf(x2)), x3);

to (assuming a is also integer):

BigInteger result = new BigIntger(String.valueOf(x1)).pow(new BigInteger(String.valueOf(x2))).multiply(new BigIntger(String.valueOf(a))).mod(x3);

This time I didn't use modPow directly but rather first pow then mod because you want to mod ((x ^ y) * a), right?
Small correction:
the line should be:
new BigInteger(String.valueOf(x1)).pow(x2).multiply(new BigInteger(String.valueOf(a))).mod(x3);

I had 2 spelling mistakes Intger -> Integer.
and also pow seems to accept integer and not BigInteger.
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of yongeng

ASKER

it compiles with an error "pow(int) in java.math.BigInteger cannot be applied to (java.math.BigInteger)"
And another thing:

if you have integer you don't have to do: new BigInteger(String.valueOf(x1)) to convert it into BigInteger
you can just do: BigInteger.valueOf(x1);

So, basically the following line is equal (but shorter) to what we did before

result = BigInteger.valueOf(x1).pow(x2).multiply(BigInteger.valueOf(a)).mod(x3);
Avatar of yongeng

ASKER

hi aozarov,

a is also a big integer.....

i tried to change it to
BigInteger result3 = new BigInteger(String.valueOf(x1)).pow(x2).multiply(new BigInteger(String.valueOf(a))).mod(x3);

but its still giving the same error....
Oh, if a is big integer then you need to do:
BigInteger result3 = new BigInteger(String.valueOf(x1)).pow(x2).multiply(a).mod(x3);

or just
BigInteger result3 = BigInteger.valueOf(x1).pow(x2).multiply(a).mod(x3);
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of yongeng

ASKER

sorry aozarov, but its still giving the same error......

BigInteger result3 = new BigInteger(String.valueOf(x1)).pow(x2).multiply(a).mod(x3);

all the variables: x1, x2, x3 and a are supppose to be BigInteger.....
As I said:

change
   pow(x2)
into
   pow(x2.intValue())
pow() doesn't take a BigInteger as parameter but an int
Avatar of yongeng

ASKER

thanxs zzynx.... its working now....

sorrie i din read carefully......
>> thanxs zzynx.... its working now....
Good

>> sorrie i din read carefully......
I happens to all of us ;°)
Thanks
I am happy to hear that it worked for you (thanks zzynx).
BTW, was not x2 originally integer?
>>  where x1, x2 are integers and x3 is a BigInteger