BigInteger Wrong Answer - java

I was calculating a simple combination using java, when I define the result as double, the answer seems right, only lost some precision, but when I use the BigInteger class, the answer looks just wrong at all, I don't see why it's like that, here is the code.
import java.math.BigInteger;
import java.util.Scanner;
public class Test {
public static void main(String[] args){
Scanner in = new Scanner(System.in);
System.out.println("Please input the lottery sum");
int num = in.nextInt();
System.out.println("Please input the available sum");
int avail = in.nextInt();
//double sum = 1;
BigInteger sum = BigInteger.ONE;
for (int i = avail - 1; i >= 1;i--){
//sum = sum*(num - i) / i;
sum = sum.multiply(BigInteger.valueOf(num - i)).divide(BigInteger.valueOf(i));
}
//sum = sum * num / avail;
sum = sum.multiply(BigInteger.valueOf(num)).divide(BigInteger.valueOf(avail));
System.out.println(sum);
in.close();
}
}

The main difference between double and BigInteger is that one is using float-point maths, and other is using integer maths. This means that, when you using BigInteger, the result of every division gets truncated.

I'm not sure what you're calculating, but I suspect that the integer division is what's causing the observed differences.
I suppose that you get the same result with BigInteger and a regular int for small examples.
For example:
double:
3.0/2.0 = 1.5
(Big)Integer:
3/2 = 1
If you sum over such divisions multiple times, the discrepancy gets bigger and bigger.
Take a look at BigDecimal, that may be the solution you're after to avoid this error introduced by integer divisions.

Related

For two given positive numbers a and b. Find a raised to b. Output your number modulus 10^9+7

https://practice.geeksforgeeks.org/problems/abset-2/0/ , this is a gfg question where i am asked to output my number (a ^ b) modulus 10^9+7.
so here is my first code;
public static void main (String[] args) {
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
while(t--!=0){
int a = sc.nextInt();
int b = sc.nextInt();
int result = 1;
for(int i = 0; i<b; i++){
result = result*a;
}
System.out.println(result%1000000007);
}
}
and it is not giving the correct output for 99^928. Then i changed the data type of result into long even that's giving a negative number. Then i had to change my code like this and it worked
public static void main (String[] args) {
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
while(t--!=0){
int a = sc.nextInt();
int b = sc.nextInt();
long result = 1;
for(int i = 0; i<b; i++){
result = (result*a);
result = result%1000000007;
}
System.out.println(result);
}
here my question is when i put the result%1000000007 in the for loop how it worked, according to the problem was not i supposed to output the ultimate result modulus 10^9+7?
int and long have maximum values. Depending on a and b a^b exceeds that maximum and overflows.
The modulo operation in the end would then act on the wrong overflow value and the result would be off.
The thing with modulo is that you can apply modulo during your computation basically whenever you want without changing the result. (a + b) mod m has the same value as (a mod m + b mod m) mod m and similarly (a * b) mod m is the same as (a mod m * b mod m) mod m, that is simply how the modulo operator works. Simply play around with a few small values of a b and m on paper to see that the rules work.
It is very typical for assignments involving HUGE values to be computable only if you add some mod m steps somewhere in the mix (as long as they make sense).
99^928 is a large number with 1852 digits. The primitive data types int and long in Java don't have the storage capacity for such a number: the largest value you can store in an int is 2147483647 and the largest you can store in a long is 9223372036854775807. Operations that return larger values wrap around, returning a value that is correct modulo a power of 2, but completely unusable for most practical purposes.
If you printed out the intermediate values, you would see the result wrap around already at 99^10:
99^9 = 913517247483640899
99^10 = -1795512867667309079
This means if you wait to do the modulo operation until the last moment, you will be taking the modulo of an incorrect intermediate result. You must control how large the values get by using modulo already in the intermediate steps.
Note that Java does have classes for dealing with integers bigger than fits in a long: java.math.BigInteger. It even has a convenient and fast method for the "modular power" operation you are implementing:
BigInteger base = BigInteger.valueOf(1000000007);
BigInteger result = BigInteger.valueOf(a).modPow(BigInteger.valueOf(b), base);

I wrote this program to find if a given input is power of 2 , this program is not running for very large number such as 10^18 or so. what should i do

This is a program to check if an input is power of 2 or not. This program is running fine for inputs up to 8 digits but when I am giving input like 1018, it is not working, What should I do?
import java.util.Scanner;
public class search {
public static void main(String [] args){
//to take how many inputs are there
Scanner sc = new Scanner(System.in);
int k ;
k = sc.nextInt();
for(int i = 0 ;i<k;i++){
// input number n
long n ;
n = sc.nextInt();
if ((n > 0) && ((n & (n - 1)) == 0)){
System.out.println("YES");
}
else{
System.out.println("NO");
}
}
}
}
The problem is that 1018 is out of range of Java int, which stores numbers up to 231-1, or roughly 2*109. You can expand the range of your program by using long in place of int to accept numbers up to 9*1018, or to make it accept virtually unlimited range by using BigInteger:
BigInteger n = new BigInteger(numericString);
BigInteger test = n.and(n.subtract(BigInteger.ONE));
if (test.equals(BigInteger.ZERO)) {
...
}
You need to get your input number as String then use BigInteger class to avoid limit surpassing problem,
BigInteger inputNumber = new BigInteger(inputString);
Also, refer What does BigInteger having no limit mean? to know more about BigInteger limits.
If the long number range is enough, you can just change
n = sc.nextInt();
to
n = sc.nextLong();
At the moment, n is only set to an integer and therefore limited to the int number range.
Better Use Class BigInteger it implement Serializable, Comparable<BigInteger> .BigInteger provides operations for modular arithmetic, GCD calculation, primality testing, prime generation, bit manipulation, and a few other miscellaneous operations.
input="Number"
BigInteger number = new BigInteger(input);
//Do your stuff
Happy to help thanks
Take the input in long:
k = sc.nextLong();

how to create an Exp(-x^2) function?

I am using the "think java" book and I am stuck on exercise 7.6. The goal here is to write a function that can find . It gives you a couple hints:
One way to evaluate is
to use the infinite series expansion:
In other words, we need to add up a series of terms where the ith term
is equal to
Here is the code I came up with, but it is horribly wrong (when compared to Math.exp) for anything other than a power of 1. I don't understand why, as far as I can tell the code is correct with the formula from the book. I'm not sure if this is more of a math question or something related to how big of a number double and int can hold, but I am just trying to understand why this doesn't work.
public static void main(String[] args) {
System.out.println("Find exp(-x^2)");
double x = inDouble("Enter x: ");
System.out.println("myexp(" + -x*x + ") = " + gauss(x, 20));
System.out.println("Math.exp(" + -x*x + ") = " + Math.exp(-x*x));
}
public static double gauss(double x, int n) {
x = -x*x;
System.out.println(x);
double exp = 1;
double prevnum = 1;
int prevdenom = 1;
int i = 1;
while (i < n) {
exp = exp + (prevnum*x)/(prevdenom*i);
prevnum = prevnum*x;
prevdenom = prevdenom*i;
i++;
}
return exp;
} // I can't figure out why this is so inacurate, as far as I can tell the math is accurate to what the book says the formula is
public static double inDouble(String string) {
Scanner in = new Scanner (System.in);
System.out.print(string);
return in.nextDouble();
}
I am about to add to the comment on your question. I do this because I feel I have a slightly better implementation.
Your approach
Your approach is to have the function accept two arguments, where the second argument is the number of iterations. This isn't bad, but as #JamesKPolk pointed out, you might have to do some manual searching for an int (or long) that won't overflow
My approach
My approach would use something called the machine epsilon for a data type. The machine epsilon is the smallest number of that type (in your case, double) that is representable as that number. There exists algorithm for determining what that machine epsilon is, if you are not "allowed" to access machine epsilon in the Double class.
There is math behind this:
The series representation for your function is
Since it is alternating series, the error term is the absolute value of the first term you choose not to include (I leave the proof to you).
What this means is that we can have an error-based implementation that doesn't use iterations! The best part is that you could implement it for floats, and data types that are "more" than doubles! I present thus:
public static double gauss(double x)
{
x = -x*x;
double exp = 0, error = 1, numerator = 1, denominator = 1;
double machineEpsilon = 1.0;
// calculate machineEpsilon
while ((1.0 + 0.5 * machineEpsilon) != 1.0)
machineEpsilon = 0.5 * machineEpsilon;
int n = 0; //
// while the error is large enough to be representable in terms of the current data type
while ((error >= machineEpsilon) || (-error <= -machineEpsilon))
{
exp += error;
// calculate the numerator (it is 1 if we just start, but -x times its past value otherwise)
numerator = ((n == 0) ? 1 : -numerator * x);
// calculate the denominator (denominator gets multiplied by n)
denominator *= (n++);
// calculate error
error = numerator/denominator;
}
return exp;
}
Let me know how this works!

Different results in Java and Python when computing powers

I am trying to teach myself Java by working through the problems on projecteuler.net, as I have done previously with Python. When attempting problem 16, I replicated the method I used previously in Python. However the result output was different in the two languages. I think it is something to do with Java data types being different from Python. The problem is to sum the digits in the number 2^1000.
In Python:
def sumdigits(n):
s = 0
while n > 0:
s = s + (n % 10)
n = n / 10
return s
print sumdigits(pow(2,1000))
In Java:
public static double SumDigits(double n){
double s = 0;
while (n > 0){
s = s + (n % 10);
n = n / 10;}
return s;
}
System.out.println(SumDigits(Math.pow(2,1000)));
Python produced the correct result and Java produced 1197.1463275484991
Why would these be different?
In Java, double cannot accurately represent 2^1000. As a floating-point number, Math.pow(2,1000) is 1.0715086071862673E301.
To get the result that you want, use BigInteger which preserves the actual value of 2^1000.
public static BigInteger sumDigits(BigInteger n) {
BigInteger num = n;
BigInteger sum = BigInteger.ZERO;
BigInteger ten = BigInteger.valueOf(10);
while (num.compareTo(BigInteger.ZERO) > 0) {
sum = sum.add(num.mod(ten));
num = num.divide(ten);
}
return sum;
}
public static void main(String[] args) {
System.out.println(sumDigits(BigInteger.valueOf(2).pow(1000)));
}
The output of the above code is 1366.
The basic number types in Java are int and double. Both cannot handle a number with 1000 bits. Python has a arbitrary large integer type builtin. For Java you have to find another solution.
In languages with arbitrary large integer arithmetics this problem is trivial
print sum(int(x) for x in str(2**1000))
If you don't have this tool, you have to code multiplication by two on your own.

Why java.Math.BigInteger bugs out after a certain limit?

Am trying to print the sum of digits in 2^n for n = 1 to 1000.
Here's what I've done.
public static void main(String[] args) {
int n = 1000;
for (int i = 1; i < n; i++) {
BigInteger power = BigInteger.valueOf((int)Math.pow(2, i));
int sum = 0;
while (power.intValue() > 0) {
sum += power.intValue() % 10;
power = power.divide(BigInteger.valueOf(10));
}
System.out.print(sum + " ");
}
}
It works only till about 2^30 or so and then prints the same result, 46, for the rest.
I tried a similar thing using "long long" in C and that printed 0's after a similar limit.
According to the answers, I changed
BigInteger power = BigInteger.valueOf((int)Math.pow(2, i));
to
BigInteger power = BigInteger.valueOf(2).pow(i);
and 46 changed to 0. Just like C.
Still not working...
You're using Math.pow to generate the value you should use the BigInteger functions to do so instead.
The sum should be stored in a BigInteger as well not an int.
You are doing integer arithmetic and then putting it into a biginteger. Use a biginteger's pow method instead.
Because you aren't using BigInteger.
Computing numbers using BigInteger doesn't let you magically store their sum in an int.
Similarly, passing an int to BigInteger.valueOf() doesn't magically make that int bigger.
You're calling Math.pow() with regular integers, not BigIntegers. You're calling it on integer literals.
You want this:
int i = 7; //or whatever power
BigInteger k = BigInteger.valueOf(2);
k = k.pow(i);

Categories

Resources