Why isn't java doing math correctly [duplicate] - java

This question already has an answer here:
Java Division error
(1 answer)
Closed 7 years ago.
I was trying to create a probability calculator for fun, but for some reason, java gets the incorrect answer when I divide two numbers. Here is my code....
import javax.swing.JOptionPane;
public class ProbabilityCalculator {
public static void main(String args[]) {
String a = JOptionPane.showInputDialog("One out of.....");
int x = Integer.parseInt(a);
int numLoops = 1000;
int y = 0;
int n = 0;
for (int i = 0; i < numLoops; i++) {
int result = (int) (Math.random() * x + 1);
int result2 = (int) (Math.random() * x + 1);
if (result == result2)
y++;
else
n++;
}
System.out.println(y);
System.out.println(numLoops);
System.out.println(y/numLoops);
double d = (y/numLoops) * 100; //get it? double d??
JOptionPane.showMessageDialog(null, "Out of " + numLoops + " trials, "
+ y + " times it worked, while " + n + " times it didn't.");
JOptionPane.showMessageDialog(null, "Your percentage was " + d
+ "%.");
System.exit(0);
}
}
When I ran this code one time, y was 514, numLoops was 1000, but d would be 0, when d is supposed to be 51.4 (514 / 1000 * 100). Why is this happening?

y/numLoops will be an integer since both arguments are ints. Try (double)y/numLoops or y/(double)numLoops instead.
If you decompose double d = (y/numLoops) * 100; you'll get something similar to those steps:
int r = y/numLoops; - according to the spec an operation having two integer operands will have an int result.
double d = r * 100 here r will be 0 due to being int.

Related

Why do I get "NaN" as Outprint`?

I want to calculat Pi with Java. With S. Ramanujan formel.
Heres my code:
public class PiV5 {
public static void main(String[] args) {
int a = 4;
double pi = 0;
int b = 3;
int fakult = 3;
int x = 3;
long y = 1;
for (int i =1; i <= 50; i++) {
int n = i*4;
long fakultaet = 1;
long fakultae2 = 1;
int bh = i;
for (int g=1; g<=n; g++) {fakultaet = fakultaet * g;}
for (int l=1; l<=bh; l++) {fakultae2 = fakultae2 * l;}
pi = ((fakultaet * (1103 + (26390*i)))/Math.pow(fakultae2, 4) * Math.pow(396, 4*i));
};
System.out.println("Pi nach ein paar Rechnungen: " + (Math.sqrt(8)/9801)*pi);
}
}
Thanks for ur help, if you could help me
As Andreas mentioned in the comments this calculation results in a numeric overflow, because the values getting to large even for long data types.
The maximum steps you can do with your algorithm right now is 5, because 20! = 2432902008176640000, 21! = -4249290049419214848 which is caused by the numeric overflow.
But even then you have a little error in your code, because you forgot to sum up the values in the loop:
pi += ((fakultaet * (1103 + (26390 * i))) / Math.pow(fakultae2, 4) * Math.pow(396, 4 * i));
To get a better accuracy also use double values for the constant values:
pi += ((fakultaet * (1103d + (26390d * i))) / Math.pow(fakultae2, 4) * Math.pow(396, 4 * i));
Using that with 5 iterations will result in the following:
Pi nach ein paar Rechnungen: 4.0513767058512194E63
This is not quite a good result for PI.
To improve it and get better accuracy you could use BigDecimal class.

Maximum value of int breaking my for loop?

I was attempting to solve this morning's Codeforces problem Div 2C: http://codeforces.com/contest/716/problem/C
This problem has the potential to loop up to 100,000 times so the parameter here can be up to 100,000. Loop seems to break when passing in 100,000 (and possibly earlier) and i is declared as an int:
public void solve(int a) {
double x = 2;
double y = 0;
double n = 0;
double target = 0;
double lcm = 0;
for (int i = 1; i <= a; i++) {
lcm = (i + 1) * i;
y = ((lcm * lcm) - x) / i;
n = (y * i) + x;
if (Math.sqrt(n) % (i + 1) == 0) {
x = Math.sqrt(n);
String answer = String.format("%.0f", y);
System.out.println("this is i: " + i);
System.out.println(answer);
}
}
}
Here is the relevant output:
this is i: 46337
99495281029892
this is i: 46338
99501722706961
this is i: 46340
99514606895203
this is i: 65535
32769
Doing a quick search on Stack overflow shows that the number 65535 is associated with a 16-bit unsigned int, but java uses 32bit ints. Changing the type to double works, as does simply looping 100,000 times and printing without the code logic. I understand that 100,000^2 IS above the maximum int limit, but this value is never stored as an int in my code. What's going on here?
The following line generates an out of bounds int before converting the result to double:
lcm = (i + 1) * i;
The above is essentially the same as:
lcm = (double)((i + 1) * i);
or
int temp = (i + 1) * i;
lcm = (double) temp;
Instead try (first converting to double and then taking what is similar to a square):
lcm = (i + 1.0) * i;

How to calculate circumference with random numbers?

I need to print the circumference with Math.random() * Math.Pi; but i'm doing something wrong or missing something. Each random generated number equals the radius of the circle. My idea was to calculate Pi in the getRandomNumberInRange method but when I do, I get error:
Bad operand for type double
import java.util.Random;
import java.util.Scanner;
final static double PI = 3.141592564;
static Scanner sc = new Scanner(System.in);
public static void main(String[] args) {
//ask the player to enter a number less than or equal to 18 and higher to 9.
System.out.println(" Please enter a number less than or equal to 18 and above 9: ");
int random = sc.nextInt ();
//send error message if bad input
if (random < 9 || random > 18) {
System.out.println(" Error. Unauthorized entry . You need to enter a number less than or equal to 18 and above 9 ");
} else
//If the answer is yes , generate nine different random numbers from 0.
for (int i = 0; i < 9; i++) {
double surface = PI * (random * 2);
System.out.println(getRandomNumberInRange(9, 18) + " : " + " The circumference is : " + surface );
}}
The method called:
private static int getRandomNumberInRange(int min, int max) {
Random r = new Random();
return r.nextInt((max - min) + 1) + min;
}
You call getRandomNumberInRange() in the for loop, but don't assign it to anything, or use it.
This is probably closer to what you want:
for (int i = 0; i < 9; i++) {
int r2 = getRandomNumberInRange(9, 18);
double surface = PI * (r2 * 2);
System.out.println(r2 + " : " + " The circumference is : " + surface);
}

Is it possible to increase array index in a loop?

So my problem is that if you want to get a new calculation, the operaotr in my array should change. How can i do that? im trying this now for hours :/ this is how far i got.
so first it starts with + and whan you choose to get a new calculation the next one should be - and so on....
so i need to switch the "operator[0]"
private static void mathGame() {
char[] operator = {'+', '-', '*', '/'};
int x;
int y = 0;
Scanner input = new Scanner(System.in);
do {
int operand1 = (int) (Math.random() * (100 - 1) + 1);
int operand2 = (int) (Math.random() * (100 - 1) + 1);
System.out.println("Solve");
System.out.println(operand1 + " " + operator[0] + " " + operand2);
x = input.nextInt();
// operator [1]++;
if (x == evaluate(operand1, operator[0], operand2)) {
System.out.println("True!");
System.out.println("New Challange?");
y = input.nextInt();
//operator[1]++;
} else if (x != evaluate(operand1, operator[0], operand2)) {
System.out.println("False!");
System.out.println("New Challange?");
y = input.nextInt();
//operator[1]++;
}
} while (y == 1);
}
You need to define a variable outside of your loop (int i = 0;) and then have this instruction inside the loop (maybe before "} while (y == 1);":
i = (i + 1) % 4; (4 is size of your operators array).
p.s. I think you need to give more details about your question and elaborate your question in order to make it more clear for future readers.

Write a program which reads two non-negative integers 'x' and 'y' (where x < y) and then prints three random integers in the range x...y

import java.util.Scanner;
import java.util.Random;
public class Lab04b
{
public static void main(String []args)
{
Random generator = new Random ();
Scanner scan = new Scanner(System.in);
int num1;
int num2;
int num3;
System.out.println("Enter X:");
num1 = scan.nextInt();
System.out.println("Enter Y:");
num2 = scan.nextInt();
num3 = generator.nextInt(num2) + num1;
System.out.println("3 random integers in the range " + num1 + ".." + num2 + " are: " + num3);
}
}
I am stuck on how to get 3 random integers between the x and y range. Y being the biggest integer.
The trick is finding the difference between x and y. Here is what you need to do -
int diff = Math.abs(num1 - num2);
num3 = generator.nextInt(diff) + Math.min(num1, num2);
Just do it 3 times and you get your 3 numbers.
From the docs
nextInt(int n)
Returns a pseudorandom, uniformly distributed int value between 0
(inclusive) and the specified value (exclusive), drawn from this
random number generator's sequence.
so random.nextInt(Y) would give you numbers 0..Y, I guess you are missing how to get the lower bound correctly.
X + random.nextInt(Y-X) does the trick.
Read the documentation. The nextInt(n) function returns an Integer in [0, n). So, in your case, you can use the formula min + nextInt(max-min), which will give you a number in [min, max).
Random generator = new Random();
int max = (x >= y ? x : y);
int min = (x < y ? x : y);
int aRandomNumber = min + generator.nextInt(max-min);
Firstly have a loop which will run 3 times, to generate 3 random numbers(as you said you need 3 random numbers, but you're just generating only 1).
Next, the pattern you've used to generate a random number seems to be flawed. You can use the below type 1 pattern to accomplish that.
min + Math.random() * ((max - min) + 1));
Or this type 2 pattern
rand.nextInt((max - min) + 1) + min;
So you can do something like this:-
for (int i = 0; i < 3; i++) {
// Type 1
num3 = num1 + (int)(Math.random() * ((num2 - num1) + 1));
// Type 2
// num3 = generator.nextInt((num2 - num1) + 1) + num1;
System.out.println("3 random integers in the range " + num1 + ".." + num2 + " are: " + num3);
}
P.S:- You need to first determine the max and min, yourself. I've just given the pattern and a sample.
import java.util.Scanner;
public class GenerateRandomX_Y_numbers {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter the numbers x and y: ");
int x = Math.abs(sc.nextInt()), y = Math.abs(sc.nextInt());//we need //non-negative integers, that is why we use here Math.abs. which means the //absolute value
print3RandomNumbers_between_x_and_y(x, y);
}
public static void print3RandomNumbers_between_x_and_y(int x, int y) {//here //I create a method with void type that takes two int inputs
boolean isTrue = (x < y);//according to our conditions X should less //than Y
if (isTrue) {//if the condition is true do => generate three int in the //range x .... y
int rand1 = (int) (Math.random() * (y - x) + 1);// y - x means our //range, we then multiply this substraction by Math.random()
int rand2 = (int) (Math.random() * (y - x) + 1);//the productof this //multiplication we cast to int type that is why we have
int rand3 = (int) (Math.random() * (y - x) + 1);//(int) before //(Math.random() * (y - x));
System.out.println("rand1 = " + rand1);//
System.out.println("rand2 = " + rand2);//
System.out.println("rand3 = " + rand3);//here print our result
} else
System.out.println("Error input: X should be less than Y. Try it again!");//if the condition is not true, i mean if x is not less than or equal //to Y, print this message
}
}

Categories

Resources