• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 429
  • Last Modified:

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
0
yongeng
Asked:
yongeng
  • 16
  • 13
  • 6
  • +3
3 Solutions
 
CEHJCommented:
Try

% x3.doubleValue();
0
 
mightyoneCommented:
double y1 = (Math.pow(x1, x2)) % (double)x3;

or

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



0
 
zzynxSoftware engineerCommented:
mightyone,
that results twice in
  inconvertible types

You can't cast a double to a BigInteger and vice versa
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
aozarovCommented:
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.
0
 
Mayank SAssociate Director - Product EngineeringCommented:
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.
0
 
Mayank SAssociate Director - Product EngineeringCommented:
BigInteger bigInt = new BigInteger ( Long.toString ( Math.pow ( x1, x2 ) ) ) ;
BigInteger remainder = bigInt.remainder ( x3 ) ;
int r = remainder.intValue () ; // or long r = remainder.longValue () ;
0
 
aozarovCommented:
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()
0
 
aozarovCommented:
mayankeagle, I think remainder works differently then mod when it comes to negative values.
0
 
Mayank SAssociate Director - Product EngineeringCommented:
>> 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?
0
 
yongengAuthor Commented:
>> 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
0
 
aozarovCommented:
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"
0
 
aozarovCommented:
I think you should go all the way with BigInteger so you will not have any "trancation" problems.
0
 
Mayank SAssociate Director - Product EngineeringCommented:
>> 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.
0
 
aozarovCommented:
mayankeagle, man you are living on the edge ;-)
Good night.
0
 
aozarovCommented:
I was talking about the reminder thing (if you didn't get my joke) no offend :-)
0
 
yongengAuthor Commented:
>>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)"
0
 
yongengAuthor Commented:
>>BigInteger result = new BigInteger(x1).modPow(new BigInteger(x2). x3);

When I tried this, it compiles with the same error.....
0
 
Mayank SAssociate Director - Product EngineeringCommented:
Try: BigInteger bigInt = new BigInteger ( Double.toString ( Math.pow ( x1, x2 ) ) ) ;
0
 
yongengAuthor Commented:
>> 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.....
0
 
Mayank SAssociate Director - Product EngineeringCommented:
What is the error that it gives? Please post your updated code.
0
 
aozarovCommented:
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
0
 
yongengAuthor Commented:
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
0
 
yongengAuthor Commented:
Hi aozarov,

I tried to change the codes to yours but after running with the test values, the result is always 0....
0
 
yongengAuthor Commented:
>> 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 :)
0
 
aozarovCommented:
:-)
0
 
yongengAuthor Commented:
hi aozorov,

can you roughly explain how it the statement works?

espacially the modPow....
0
 
aozarovCommented:
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 ....)
0
 
yongengAuthor Commented:
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?
0
 
aozarovCommented:
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?
0
 
aozarovCommented:
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.
0
 
aozarovCommented:
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);
int a = 2;
result = new BigInteger(String.valueOf(x1)).pow(x2).multiply(new BigInteger(String.valueOf(a))).mod(x3);
System.out.println(result);
}
}

knoppix@ttyp1[knoppix]$ javac Tmp.java
knoppix@ttyp1[knoppix]$ java Tmp
4
3

0
 
yongengAuthor Commented:
it compiles with an error "pow(int) in java.math.BigInteger cannot be applied to (java.math.BigInteger)"
0
 
aozarovCommented:
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);
0
 
yongengAuthor Commented:
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....
0
 
aozarovCommented:
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);
0
 
zzynxSoftware engineerCommented:
>> it compiles with an error "pow(int) in java.math.BigInteger cannot be applied to (java.math.BigInteger)"

You can convert this BigInteger to an int via intValue()

so change
   pow(x2)
into
   pow(x2.intValue())
0
 
yongengAuthor Commented:
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.....
0
 
zzynxSoftware engineerCommented:
As I said:

change
   pow(x2)
into
   pow(x2.intValue())
0
 
zzynxSoftware engineerCommented:
pow() doesn't take a BigInteger as parameter but an int
0
 
yongengAuthor Commented:
thanxs zzynx.... its working now....

sorrie i din read carefully......
0
 
zzynxSoftware engineerCommented:
>> thanxs zzynx.... its working now....
Good

>> sorrie i din read carefully......
I happens to all of us ;°)
0
 
zzynxSoftware engineerCommented:
Thanks
0
 
aozarovCommented:
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
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 16
  • 13
  • 6
  • +3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now