subtraction operation with 2 random numbers - java

I am trying to create a simple math game for my son. I have the addition operation working perfect. My problem is with subtraction. I am using the same code as my addition operation, problem is sometimes the 2nd number is larger than the 1st number resulting in a negative number. I need help correcting the order of the random numbers so the 1st number is greater than or equal to the 2nd number. Please help.
Scanner input = new Scanner(System.in);
int answer;
public static void main(String[] args) {
// TODO code application logic here
int SIDES = 6;
int a = 1 + (int) (Math.random() * SIDES);
int b = 1 + (int) (Math.random() * SIDES);
System.out.println("What is " + a + " - " + b + " = ");
int difference = a - b;
Scanner one = new Scanner (System.in);
System.out.println("What is the answer?");
int answer = Integer.parseInt(one.next());
//int answer = one.next();
System.out.println("your answer is " + answer);
if (answer==difference) {
System.out.println("You are correct!");
System.out.println("You gain 5 points");
}
else{
System.out.println("You are wrong.");
System.out.println("The correct answer is " + difference);
System.out.println("You lose 5 points");
}

Just use an inequality operator to compare their values, than subtract from the larger one:
int difference = a > b ? a - b : b - a;
// ^ Inequality operator
If the ? operator is confusing you, you can alternatively write it like this:
int difference;
if(a > b) difference = a - b;
else difference = b - a;
You can read more about operators such as ?, >, &&, ||, etc. on the Equality, Relational, and Conditional Operators page.

There are many ways, but in order not to mess up your code, an easy fix would be checking the 2 generated random numbers before assigning them to a and b:
int r1 = (int) Math.random()*SIDES;
int r2 = (int) Math.random()*SIDES;
int a = Math.max(r1, r2);
int b = Math.min(r1, r2);
This way, a will always be greater or equals to b.

You can make sure that your b never becomes bigger than a by adjusting your random number generation logic:
int b = 1 + (int) (Math.random() * a);
That's probably better than swapping the numbers, because swapping will skew a to the high end (close to SIDES) which may not be what you want.

Since you are only subtracting two numbers you can simply use if(a >= b) then a - b else b - a to control the order.
If there are more numbers in the question you can always put all the random numbers into an array and sort them before generating the question.

Related

Problems Generating A Math.random Number, Either 0 or 1

I want a random number, either 0 or 1 and then that will be returned to main() as in my code below.
import java.util.Scanner;
public class Exercise8Lab7 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int numFlips = 0;
int heads = 0;
int tails = 0;
String answer;
System.out.print("Please Enter The Number Of Coin Tosses You Want: ");
numFlips = input.nextInt();
for(int x = 1;x <= numFlips; x++){
if(coinToss() == 1){
answer = "Tails";
tails++;
}
else{
answer = "Heads";
heads++;
}
System.out.print("\nCoin Toss " + x + ": " + answer);
}
System.out.println("\n\n====== Overall Results ======" +
"\nPercentage Of Heads: " + (heads/numFlips)*100 + "\nPercentage Of Tails: " + (tails/numFlips)*100);
}
public static int coinToss(){
double rAsFloat = 1 * (2 + Math.random( ) );
int r = (int)rAsFloat;
return r;
}
}
Many solutions had been suggested to use the util.Random option which I have done and works perfectly but I want to sort out why I can't get this to work. Obviously I want the number to be an int myself so I convert it to an int after the random number has been generated. But no matter what I add or multiply the Math.random() by, it will always all either be Heads or all either be Tails. Never mixed.
Try this) It will generate number 0 or 1
Math.round( Math.random() ) ;
You could use boolean values of 0 or 1 based on value of Math.random() as a double between 0.0 and 1.0 and make the random generator much simpler. And you can get rid completely of the coinToss() method.
if(Math.random() < 0.5) {
answer = "Tails";
tails++;
}
Remove the coin toss method and replace the first conditional with the code above.
Math.random(); by itself will return a value between 0.0 and less than 1.0. If the value is in the lower half, [0.0, 0.5), then it has the same probability of being in the upper half, [0.5, 1.0). Therefore you can set any value in the lower half as true and upper as false.
Wierd that no one is using a modulo division for the random number.
This is the simplest implementation you can get:
Random rand = new Random();
int randomValue = rand.nextInt() % 2;
Math.round(Math.random()) will return either 0.0 and 1.0. Since both these values are well within the limits of int range they can be casted to int.
public static int coinToss(){
return (int)Math.round(Math.random());
}
(int)(Math.random()*2) also works fine in this case
its not working because of the integer math you are using, the call to 2+ Math.Random is pretty much always giving you a answer between 0.0 and 1.0.
so assuming that you recieve 0.25 as your result your maths is as follows
double d = 1* (2 + 0.25); // (result = 2
Then you are checking to see if your result == 1 ( which it never will. )
A better result would be to declare java.util.Random as a class variable and call random.nextBoolean() and simply perform your heads/tails calculation on that.
If you were to continue to use Math.random() and lets say
return Math.random() < 0.5
Your results would be ever so slightly skewed due to the fact that Math.random() cannot return 1.0, due to the fact that the java API specification states:
"Returns a double value with a positive sign, greater than or equal to 0.0 and less than 1.0."
Math.random() returns a random float in the range [0.0,1.0)--that means the result can be anything from 0 up to but not including 1.0.
Your code
double rAsFloat = 1 * (2 + Math.random( ) );
will take this number in the [0.0,1.0) range; adding 2 to it gives you a number in the [2.0,3.0) range; multiplying it by 1 does nothing useful; then, when you truncate it to an integer, the result is always 2.
To get integers from this kind of random function, you need to figure out how many different integers you could return, then multiply your random number by that. If you want a "0 or 1" answer, your range is 2 different integers, so multiply Math.random() by 2:
double rAsFloat = 2 * Math.random();
This gives you a random number in the range [0.0,2.0), which can then be 0 or 1 when you truncate to an integer with (int). If, instead, you wanted something that returns 1 or 2, for example, you'd just add 1 to it:
double rAsFloat = 1 + 2 * Math.random();
I think you've already figured out that the Random class gives you what you want a lot more easily. I've decided to explain all this anyway, because someday you might work on a legacy system in some old language where you really do need to work with a [0.0,1.0) random value. (OK, maybe that's not too likely any more, but who knows.)
The problem can be translated to boolean generation as follow :
public static byte get0Or1 {
Random random = new Random();
boolean res= random.nextBoolean();
if(res)return 1;
else return 0;
}
Here it the easiest way I found without using java.util.Random.
Blockquote
Scanner input = new Scanner (System.in);
System.out.println("Please enter 0 for heads or 1 for tails");
int integer = input.nextInt();
input.close();
int random = (int) (Math.random() + 0.5);
if (random == integer) {
System.out.println("correct");
}
else {
System.out.println("incorrect");
}
System.out.println(random);
This will take a random double from (0 to .99) and add .5 to make it (.5 to 1.49). It will also cast it to an int, which will make it (0 to 1). The last line is for testing.
for(int i=0;i<100;i++){
System.out.println(((int)(i*Math.random())%2));
}
use mod it will help you!
One more variant
rand.nextInt(2);
As it described in docs it will return random int value between 0 (inclusive) and the specified value (exclusive)

How to get even/odd random number divisible by first random number

I have following code:
quesPart1 = ran.nextInt((numbersBetween - 2) + 1) + 2;
quesPart2 = ran.nextInt((numbersBetween - 2) + 1) + 2;
if(quesPart2 > quesPart1)
{
int placeHolder = quesPart1;
quesPart1 = quesPart2;
quesPart2 = placeHolder;
}
//if first part is even
if(quesPart1 % 2 == 0)
{
if(quesPart2 % 2 != 0)
{
--quesPart2;
}
}
else
{
if(quesPart2 % 2 == 0)
{
++quesPart2;
}
}
Above code make sure that if quesPart1 is greater than quesPart2 and both are even or both are odd numbers. Now i want to get only random numbers which are also divisible by one another. Like if i divide quesPart1 by quesPart2 i get integer not decimal number. Any ideas how i can do that without adding too much complexity to above code.
You can do something like:
int div = quesPart1 / quesPart2;
quesPart1 = div * quesPart2;
add this code at the bottom of your code.
Like if i divide quesPart1 by quesPart2 i get integer not decimal number.
Keep it simple: generate random numbers and take their product. Example:
quesPart2 = ran.nextInt(UPPER_BOUND);
int temp = ran.nextInt(UPPER_BOUND);
questPart1 = temp * quesPart2;
Specifying the range, as in the original question, is left an an exercise to the reader. (What, you didn't think I was going to do all the thinking for you, did you? ;-)
Look into the modulus operator, a % b. It returns the left over amount when a is divided by b. When b cleanly divides into a, such that there is no decimal part, a % b will be zero.
In order to generate a number that is divisible by another, given two random numbers, a and b, simply multiply a by b. This will give you c, a number that is a multiple of both a and b, and therefore dividable by both cleanly without remainder.
I have come up with this simple function and a do while loop that is easy to implement.
// This is a simple function to set the min and max integers you want
const getRandomIntInclusive = (min, max) => {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
//Define some variables variables
let firstNo = 0
let secondNo = 0
let isDivisible = 0;
//generate random ints until first number is divisible to second number
do {
//get random int between 1-9 for the first and second integer
firstNo = getRandomIntInclusive(1, 9)
secondNo = getRandomIntInclusive(1, 9)
isDivisible = firstNo % secondNo; //Check if it's fully divisible
}
while (isDivisible != 0) //Run until it is fully divisible
To generate Random numbers in java you can use ran.nextInt() or please refer to this link to see how to generate random numbers.
store those 2 random numbers (as num1 and num2).
To verify whether the solution after dividing num1 and num2 is integer or not, use this method:
sol = num1 / num2
if (sol == (int)sol)
{
... //true if the solution is an integer
}

Issue with Java simple arithmetic

I'm working on a small Java program, and somewhere, my calculations are going awry. My code is as follows:
import java.io.*;
import java.util.*;
import java.text.*;
public class NumManip
{
public static void main(String args[])
{
Scanner numGetter = new Scanner(System.in);
final int MULT_1 = 9;
final int MULT_2 = 12345679;
final int MULT_3 = 1000;
int poorHatedNumber;
System.out.print("Enter a digit between 1 and 9 that you dislike: ");
poorHatedNumber = numGetter.nextInt();
int num1 = poorHatedNumber * MULT_1, num2 = num1 * MULT_2;
long num3 = num2 * MULT_3;
System.out.println();
System.out.println(" " + poorHatedNumber);
System.out.println(" " + "x" + MULT_1);
System.out.println(" __");
System.out.println(" " + num1);
System.out.println(" x" + MULT_2);
System.out.println(" __");
System.out.println(" " + num2);
System.out.println(" x" + MULT_3);
System.out.println("____________");
System.out.println(num3);
}
}
I've tryed printing num1, num2, and num3 on the screen to see what the problem is, and num1 is right, num2 is right, and num3 is freaky. My input is 9, and the first calculation multiplies by 9 and gets 81. Then it multiplies that by 12345679 and gets 999999999, and then it multiplies by 1000 and gets -727380968. What's wrong with that last step? I'm REALLY new to Java, and I don't get the issue.
999999999 * 12345679 = 1.234567898765432e+16 which is way bigger than the maximum value of an int which is 2,147,483,647
Since Java uses 2-compliment method to store int number (meaning that the leftmost bit is turned on when the number is negative) this calculation "overflows" (carry-over) to the that bit which results in a negative result.
For calculation with such big numbers you should use BigDecimal
As num2 and num1 both are integer, so integer multiplication happened and it exceeds the max of integer value.
long num3 = (long)num2 * MULT_3;
I think you're resulting in a number bigger than the datatype can handle, and as the datatype is signed, it wraps around into the negatives.
Don't worry, it's not such a silly mistake really. The whole "numbers are usually a fixed size"-deal confuses just about everyone initially. Now that you know what's up, here's something even weirder. It's not really an answer to your question, but now that you've just seen an example of "bad overflow", you might find this interesting.
Consider an odd number x. There is a number y such that x * y == 1. That number y is called the modular multiplicative inverse, and it can easily be computed (see Hacker's Delight, exact division by a constant). This may seem really counter intuitive, because it essentially allows a weird kind "division" that only works if the number was an exact multiple of the divisor, and in general it allows you to "undo" a multiplication by an odd number. For example, if you have a = 3 * b, then b = -1431655765 * a - regardless of any overflow in either multiplication, so overflow need not be "destructive".

How would i get a double value from an integer in java? [duplicate]

This question already has answers here:
Integer division: How do you produce a double?
(11 answers)
Closed 10 years ago.
So i am having a difficult time trying to figure out how to get the values to come out properly. All of the math is correct, but it only stating whole numbers. For example, when i input the numbers 87, 42, and 94, the average should come out 74.3 repeating. Yet it only comes out 74.0 for me. Same goes with the average for lowest score.
Scanner keyboard = new Scanner(System.in);
int a;
int b;
int c;
double grade;
double avg;
double avg2 = 0;
System.out.print("Enter score number 1: ");
a = keyboard.nextInt();
System.out.print("Enter score number 2: ");
b = keyboard.nextInt();
System.out.print("Enter score number 3: ");
c = keyboard.nextInt();
avg = ((a + b + c) / 3);
System.out.println("The average is: " + avg);
if (a < b && a < c)
{
System.out.println("The lowest score was: " + a);
System.out.println("The average without the lowest score is: " + ((b + c) / 2));
avg2 = ((b + c) / 2);
}
if (b < a && b < c)
{
System.out.println("The lowest score was: " + b);
System.out.println("The average without the lowest score is: " + ((a + c) / 2));
avg2 = ((a + c) / 2);
}
if (c < a && c < b)
{
System.out.println("The lowest score was: " + c);
System.out.println("The average without the lowest score is: " + ((a + b) /2));
avg2 = ((a + b) / 2);
}
You must cast the sum in the numerator of your avg expression to a double or use a double in the denominator:
avg = ((double)(a + b + c) / 3);
or
avg = ((a + b + c) / 3.0);
When you use all ints on the right hand side, the answer is calculated as an int before it is assigned to the double. This is why you are getting a rounded answer.
To fix, one option is to add decimal places to all your denominators like so
avg = ((a + b + c) / 3.0d);
This will force the operation to happen in double
A division between two ints will return an int. To cause the division that returns double, one of the operands must be a double, like so:
avg = ((a + b + c) / 3.0);
This is how operators work in Java. If you have any arithmetic operation, say division, in which both operands are integer then the operator will yield an integer. It is possible to loose some information in such division operations.
In your case, though you are assigning the result to a variable of type double, the assignment operator is executed after division operator is finished.
If you do not want to loose information, you can typecast any of the operand to desired type (in your case, to double).
avg = (double)(a + b + c) / 3;
Or
avg = (a + b + c) / (double)3;
Now, in above statements, division operator has two operands of different types. So the result will of type which is superior among the two.

generate random number with restrictions

I'm new to programming in general so I'm trying to be as specific as possible in this question.
There's this book that I'm doing some exercises on. I managed to do more than half of what they say, but it's just one input that I have been struggling to find out.
I'll write the question and thereafter my code,
"Write an application that creates and prints a random phone number of the form XXX-XXX-XXXX. Include the dashes in the output. Do not let the first three digits contain an 8 or 9 (but don't be more restrictive than that), and make sure that the second set of three digits is not greater than 742. Hint: Think through the easiest way to construct the phone number. Each digit does not have to be determined separately."
OK, the highlighted sentence is what I'm looking at.
Here's my code:
import java.util.Random;
public class PP33 {
public static void main (String[] args) {
Random rand = new Random();
int num1, num2, num3;
num1 = rand.nextInt (900) + 100;
num2 = rand.nextInt (643) + 100;
num3 = rand.nextInt (9000) + 1000;
System.out.println(num1+"-"+num2+"-"+num3);
}
}
How am I suppose to do this? I'm on chapter 3 so we have not yet discussed if statements etcetera, but Aliases, String class, Packages, Import declaration, Random Class, Math Class, Formatting output (decimal- & numberFormat), Printf, Enumeration & Wrapper classes + autoboxing. So consider answer the question based only on these assumptions, please.
The code doesn't have any errors.
Thank you!
Seeing as this appears to be homework I feel like an explanation of what is happening should be given.
You have three sets of numbers you need to generate.
The first number has the most requirements. It has to be greater than 100 but not contain an 8 or 9.
You ensure it will always be greater than 100 by using:
(rand.nextInt(7)+1) * 100.
This says, generate a random number between 0 and 6. Add 1 to that number to ensure that it can never be 0. So if it picks 0, +1 is added making it 1. If it picks 6, +1 is added making it 7, etc. This satisfies rule #1 and rule #2.
You ensure the first number never has an 8 or 9.
(rand.nextInt(8) * 10) + rand.nextInt(8)
Genreate a random number from 0-7. The *10 makes sure it will be in the tenth position while the last one places the number in the last position.
Instead of trying to fix the other answer as it also uses DecimalFormat incorrectly.
package stackoverflow_4574713;
import java.text.DecimalFormat;
import java.util.Random;
public class Main {
public static void main(String[] args) {
Random rand = new Random();
int num1 = (rand.nextInt(7) + 1) * 100 + (rand.nextInt(8) * 10) + rand.nextInt(8);
int num2 = rand.nextInt(743);
int num3 = rand.nextInt(10000);
DecimalFormat df3 = new DecimalFormat("000"); // 3 zeros
DecimalFormat df4 = new DecimalFormat("0000"); // 4 zeros
String phoneNumber = df3.format(num1) + "-" + df3.format(num2) + "-" + df4.format(num3);
System.out.println(phoneNumber);
}
}
Output:
662-492-1168
For the first three digits, you need to generate each digit separately. See variables i1, i2, and i3 below.
For the three digits, any number between 0 and 741 should work.
For the final set of four digits, any number between 0 and 9999 should work.
The trick here is how you format the output. You could do it with a NumberFormat object, but I chose to do it with the String.format() method. In it, you specify how you want each number to be formatted. So, I used the format string "%d%d%d-%03d-%04d". The %d inserts a base-10 formatted integer into the string. The %03d makes sure that it is three characters wide and that any additional space is left-padded with a 0. In other words, 4 is formatted as "004" and 27 is formatted as "027". The %04d works similarly, except it is four characters wide.
Here's how you put it all together.
Random r = new Random();
int i1 = r.nextInt(8); // returns random number between 0 and 7
int i2 = r.nextInt(8);
int i3 = r.nextInt(8);
int i4 = r.nextInt(742); // returns random number between 0 and 741
int i5 = r.nextInt(10000); // returns random number between 0 and 9999
String phoneNumber = String.format("%d%d%d-%03d-%04d", i1, i2, i3, i4, i5);
System.out.println(phoneNumber);`
Hmm, just a really simple idea to change this to
num1 = rand.nextInt(8)*100 + rand.nextInt(8)*10 + rand.nextInt(8);
num2 = rand.nextInt(743);
For easier output you may use DecimalFormat
DecimalFormat df3 = new DecimalFormat ( "000" ); // 3 zeros
DecimalFormat df4 = new DecimalFormat ( "0000" ); // 4 zeros
System.out.println(df3.format(num1)+"-"+df3.format(num2)+"-"+df4.format(num3));
I had this same question as the first assignment for my Java class, with the caveat that we could only use the methods that we have learned in class up to that point. Therefore, we could not use the .format method. Here is what I came up with:
import java.util.Random;
/**
*
* #author
*/
public class Randnum {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Random num = new Random();
int num0, num1, num2, num3, num4, num5, num6, num7;
num0 = num.nextInt(7) + 1;
num1 = num.nextInt(8);
num2 = num.nextInt(8);
num3 = num.nextInt(643) + 101;
num4 = num.nextInt(10);
num5 = num.nextInt(10);
num6 = num.nextInt(10);
num7 = num.nextInt(10);
String randnum= "A random phone number: ";
System.out.print (randnum);
System.out.print (num0);
System.out.print (num1);
System.out.print (num2);
System.out.print ("-" + num3 + "-");
System.out.print (num4);
System.out.print (num5);
System.out.print (num6);
System.out.println (num7);
}
}
You might also want to check that the prefix is not 555
var num1 = Math.floor(Math.random()*7) + 1;
var num2 = Math.floor(Math.random()*8);
var num3 = Math.floor(Math.random()*8);
var part2 = Math.floor(Math.random()*742);
if(part2 < 100){
part2 = "0" + part2;
}else if (part2 < 10) {
part2= "00" + part2;
}else{
part2 = part2;
}
var part3 = Math.floor(Math.random()*10000);
if(part3 < 1000){
part3 = "0" + part3;
}else if (part3 < 100) {
part3 = "00"+ part3;
}else if(part3 < 10){
part3 = "000" + part3;
}else{
part3 = part3;
}
document.getElementById("demo").innerHTML= " " + num1 + num2 + num3 + "-" + part2 + "-" + part3;
public String GetRandomPhone(){
return String.format("(%03d) %03d-%04d",
(int) Math.floor(999*Math.random()),
(int) Math.floor(999*Math.random()),
(int) Math.floor(9999*Math.random()));
}

Categories