Java BigInteger factorization: division and multiplication differ - java

I'm writing a code to factorize a big number (more than 30 digit) in Java.
The number (n) is this: 8705702225074732811211966512111
The code seems to work and the results are:
7
2777
14742873817
By logic the last item should be obtainable by doing (n/(fact1 * fact2 * fact3)) and it results:
30377199961175839
I was very happy with this, but then decided to take a little test: I multiplied all the factor expecting to find n... But I didn't!
Here is my check code:
BigInteger n = new BigInteger("8705702225074732811211966512111");
BigInteger temp1 = new BigInteger("7");
BigInteger temp2 = new BigInteger("2777");
BigInteger temp3 = new BigInteger("14742873817");
BigInteger temp4 = n.divide(temp1).divide(temp2).divide(temp3);
System.out.println(n.mod(temp1));
System.out.println(n.mod(temp2));
System.out.println(n.mod(temp3));
System.out.println(n.mod(temp4));
System.out.println(n.divide(temp1).divide(temp2).divide(temp3).divide(temp4));
System.out.println(temp1.multiply(temp2).multiply(temp3).multiply(temp4));
System.out.println(n);
As you can see I simply define the number n and the factors (the last one is defined as n/(fact1 * fact2 * fact3) then check that n/eachfactor gives remainder 0.
Then I check that ((((N / (fact1)) / fact2) / fact3) / fact4) = 1
Lastly I check that fact1 * fact2 * fact3 * fact4 = n
The problems are:
n mod temp4 is not 0, but 245645763538854
fact1 * fact2 * fact3 * fact4 is different from n
but ((((N / fact1) / fact2) / fact3) / fact4) = 1
Here is the exact output:
0
0
0
245645763538854
1
8705702225074732565566202973257
8705702225074732811211966512111
This has no sense... How can the fourth factor be wrong and right at the same time?

I'm sorry to report :
8705702225074732811211966512111/(7*2777*14742873817) =
30377199961175839.8571428571
Where it should be a whole number.
So, your factorisation is wrong ... oops ..
Try bc under linux, for windows : http://gnuwin32.sourceforge.net/packages/bc.htm.
It can deal with these kind of numbers

this page says the actual factorization of your BigInteger is 7*2777*2106124831*212640399728230879

System.out.println(temp3.mod(temp1));
The above code gives 0, which means temp3 is not prime. temp4 is not a factor.

Related

calculate kth power of 2

I was solving a problem and the basic idea to calculate the power of 2 for some k. And then multiply it with 10. Result should be calculated value mod
10^9+7.
Given Constraints 1≤K≤10^9
I am using java language for this. I used 'Math.pow' function but 2^10000000 exceeds its range and I don't want to use 'BigInteger' here. Any other way to calculate such large values.
The actual problem is:
For each valid i, the sign with number i had the integer i written on one side and 10K−i−1 written on the other side.
Now, Marichka is wondering — how many road signs have exactly two distinct decimal digits written on them (on both sides in total)? Since this number may be large, compute it modulo 10^9+7.
I'm using this pow approach, but this is not an efficient way. Any suggestion to solve this problem.
My original Solution:
/* package codechef; // don't place package name! */
import java.util.*;
class Codechef
{
public static void main (String[] args) throws java.lang.Exception
{
Scanner scan = new Scanner(System.in);
int t = scan.nextInt();
while(t-->0){
long k = scan.nextInt();
long mul=10*(long)Math.pow(2, k-1);
long ans = mul%1000000007;
System.out.println(ans);
}
}
}
After taking some example, I reached that this pow solution works fine for small constraints but not for large.
while(t-->0){
long k = scan.nextInt();
long mul=10*(long)Math.pow(2, k);
long ans = mul%1000000007;
System.out.println(ans);
}
This pow function is exceeding its range. Any good solution to this.
Basically, f(g(x)) mod M is the same as f(g(x) mod M) mod M. As exponentiation is just a lot of multiplication, you can just decompose your single exponentiation into many multiplications, and apply modulo at every step. i.e.
10 * 2^5 mod 13
is the same as
10
* 2 mod 13
* 2 mod 13
* 2 mod 13
* 2 mod 13
* 2 mod 13
You can compact the loop by not breaking up the exponentiation so far; i.e. this would give the same answer, again:
10
* 4 mod 13
* 4 mod 13
* 2 mod 13
Faruk's recursive solution shows an elegant way to do this.
You need to use the idea of dividing the power by 2.
long bigmod(long p,long e,long M) {
if(e==0)
return 1;
if(e%2==0) {
long t=bigmod(p,e/2,M);
return (t*t)%M;
}
return (bigmod(p,e-1,M)*p)%M;
}
while(t-->0){
long k = scan.nextInt();
long ans = bigmod(2, k, 1000000007);
System.out.println(ans);
}
You can get details about the idea from here: https://www.geeksforgeeks.org/how-to-avoid-overflow-in-modular-multiplication/
As the size of long is 8 bytes and it is signed datatype so the range of long datatype is -(2^63) to (2^63 - 1). Hence to store 2^100 you have to use another datatype.

Same Calculation, different result?

My goal is to calculate how many percent counter out of cap is.
Now I ran over a problem, I can't find the difference between the two formulas below, as far as my mathematical understanding tells me, it's exactly the same calculation. But only the first one works, brackets make no difference.
int i = counter * 100 / cap; //works
int i = counter / cap * 100; //doesn't work
Has this got something to do with java or is it just me who's made a horrible thinking mistake?
It is not the same calculation, since you are handling integer arithmetics, which does not have Multiplicative inverse number for all numbers (only 1 has it).
In integer arithmetics, for example, 1/2 == 0, and not 0.5 - as it is in real numbers arithmetics. This will of course cause later on inconsistency when multiplying.
As already mentioned - the root of this is the fact that integer arithmetics does not behave like real numbers arithmetics, and in particular, the divide operator is not defined as a/b == a*b^-1, since b^-1 is not even defined in integer arithmetics to all numbers but 1.
Your mistake is assuming that these are just pure, abstract numbers. I assume that counter is an int... so the second version is evaluated as:
int tmp = counter / cap;
int i = tmp * 100;
Now we're dealing with integer arithmetic here - so if counter is in the range [-99, 99] for example, tmp will be 0.
Note that even your first version may not work, either - if counter is very large, multiplying it by 100 may overflow the bounds of int, leading to a negative result. Still, that's probably your best approach if counter is expected to be in a more reasonable range.
Even with floating point arithmetic, you still don't get the behaviour of "pure" numbers, of course - there are still limits both in terms of range and precision.
First case
int i = counter * 100 / cap;
is evaluated like
(counter * 100) / cap;
The second case
int i = counter / cap * 100;
is evluated like this
(counter / cap) * 100
Hence different results
In Java, operators * and / have the same precedence, so the expressions are evaluated sequentially. I.e.
counter * 100 / cap --> (counter * 100) / cap
counter / cap * 100 --> (counter / cap) * 100
So for values e.g. counter = 5, cap = 25 (expecting count and cap to be both int variables), the evaluation is in the first case: 5 * 100 = 500, then 500 / 25 = 20
In the second case, the evaluation is: 5 / 25 = 0 (integer math!), then 0 * 100 = 0.

elements not being written into array in java

So I've written a programme used to solve a concrete equation having been given one parameter int n. The code I have is:
static double getSolution1(int n)
{
double [] a = new double[n+1];
a[0] =-1;
for (int i = 1; i < n+1; i++)
{
a[i] = a[i-1] * ( ( 2 / ( 3 * n ) ) * Math.cos(2 * a[i-1]) );
}
return a[n];
}
As far as I can tell, the code works fine and should be filling in the various parts of the array. But that's not happening, apart from a[0] = -1 that I have told the programme, it is treating all other entries as 0 as though it has not undergone the loop. Using a debug, that's the only problem I can really find. How can I fix that?
2 / 3 *n would give you zero, use all floats or doubles like 2.0f 3.0f
The "2 / ( 3 * n )" is being evaluated as int; and it works out as 0.
To fix, change it to "2.0 / (3.0 * n)"
As Pulkit said, 2/3 *n yields zero. Why?
Integer division will always round down your result to the nearest whole number. So:
2 / 3 = .666
floor(.666) = 0
To prevent this, you can add f to the end of 2 or 3. That'll cause the operation to evaluate as a float rather than an integer, avoiding the rounding.
2f / 3f
You can also add d to 2 or 3. That'll cause the operation to evaluate as a double rather than an integer.
2d / 3d
the expression ( 2 / ( 3 * n ) return an integer type. so for every number between 1 and 0, int type will be 0. what you can do is to let compiler treats 2 and 3 as float type or double type. you can use 2.0 instead of 2. or 3.0 instead of 3

Generating the list of random numbers with certain average difference

I have to generate a list of random numbers and they have to have a given average difference. For example, a given average difference is 10, so these numbers are good: 1 3 5 9 15 51. What I do, is multiply the given average difference by 2 and add 1. Like this:
while (i <= 50000)
{
i += Math.random() * givenAverageDiff * 2 + 1;
list.add(i);
}
But I never get 5000 or more. In fact, it's always 4,850 or less. Why? Let's say givenAverageDiff is 10. What's my mistake? How can I fix it?
P.S. Implementation in C or PHP is also good for me.
Because you are doing "+ 1".
Let us calculate the expected difference:
E(2*10*x+1)= 2*10*E(x)+1 = 2*10*0.5+1 = 10+1. So, on an average you will get 50000/11 numbers.
You need to pick something whose expected value is equal to 10. Change it to the following and it should work:
while (i <= 50000)
{
i += Math.random() * (givenAverageDiff-1) * 2 + 1;
list.add(i);
}
Think about it in terms of the ranges you create. With your current calculation,
i += Math.random() * givenAverageDiff * 2 + 1;
you are adding between 1 and 2*givenAverageDiff to your number. The sum of 1 through 2x is (2x)(2x+1)/2, and since there are 2x options we divide by 2x to get (2x)(2x+1)/(2*2x) = (2x+1)/2 = x + 0.5.
So what you want is to have 2x+1 options, which is easiest by using a range of [0,2*x]. You can get that by adding parenthesis:
i += Math.random() * (givenAverageDiff * 2 + 1);
If you want it to always increase, then you either need use a non-uniform distribution, or a uniform distribution with a smaller range. To get a range [n,2*x-n] use
i += Math.random() * ((givenAverageDiff - n) * 2 + 1) + n;
If you use a negative value for n you can widen the range, making it possible for numbers to decrease as well.

Modulo gives unexpected result

I have some problem with numerator, denumerator and modulo. 7 / 3 = 2.3333333333 gives me a modulo of 1!? Must be some wrong? I study a non-objective ground level course, so my code is simple and I have simplified the code below. (Some lines are in swedish)
Calling the method:
// Anropar metod och presenterar beräkning av ett bråktal utifrån täljare och nämnare
int numerator = 7;
int denumerator = 3;
System.out.println("Bråkberäkning med täljare " + numerator + " och nämnare " + denumerator + " ger " + fraction(numerator,denumerator));
And the method:
// Metod för beräkning av bråktal utifrån täljare och nämnare
public static String fraction(int numerator, int denumerator) {
// Beräkning
int resultat1 = numerator / denumerator;
int resultat2 = numerator % denumerator;
return Integer.toString(resultat1) + " rest " + Integer.toString(resultat2);
}
3 goes into 7 twice with 1 left over. The answer is supposed to be 1. That's what modulo means.
7 modulo 3 gives 1. Since 7 = 2*3 + 1.
7 % 3 = 1
Just as expected. If you want the .3333 you could take the modulo and devide it by your denominator to get 1 / 3 = 0.3333
Or do (7.0 / 3.0) % 1 = 0.3333
Ehm 7 % 3 = 1
What would you expect?
Given two positive numbers, a (the dividend) and n (the divisor), a modulo n (abbreviated as a mod n) can be thought of as the remainder, on division of a by n. For instance, the expression "5 mod 4" would evaluate to 1 because 5 divided by 4 leaves a remainder of 1, while "9 mod 3" would evaluate to 0 because the division of 9 by 3 leaves a remainder of 0; there is nothing to subtract from 9 after multiplying 3 times 3. (Notice that doing the division with a calculator won't show you the result referred to here by this operation, the quotient will be expressed as a decimal.) When either a or n is negative, this naive definition breaks down and programming languages differ in how these values are defined. Although typically performed with a and n both being integers, many computing systems allow other types of numeric operands.
More info : http://en.wikipedia.org/wiki/Modulo_operation
you didn't do a question!
And if your question is just:
"...gives me a modulo of 1!? Must be some wrong?"
No, it isn't, 7/3 = 2, and has a modulo of 1. Since (3 * 2) + 1 = 7.
You are using integer operands so you get an integer result. That's how the language works.
A modulo operator will give you the reminder of a division. Therefore, it is normal that you get the number 1 as a result.
Also, note that you are using integers... 7/3 != 2.3333333333.
One last thing, be careful with that code. A division by zero would make your program crash. ;)
% for ints does not give the decimal fraction but the remainder from the division. Here it is from 6 which is the highest multiplum of 2 lower than your number 7. 7-6 is 1.

Categories