Currently in class, learning about math in Java
I got speechless when my teacher showed me this formula?
if ((int)(Math.random() * 15) == 1) {
How can something * 15 be 1?
Suppose Math.random returns 0.08907633950002491
Now according to your formula
0.08907633950002491*15 it returns 1.3361450925003737
after int type cast it will be 1
(int)(Math.random() * 15) == 1 returns true
This is because of the cast to integer
(int) Math.random()
You see Math.random() gives a random number between 0.0 and 1.0
when you cast to an integer you are effectively saying - " Throw out all the decimal places"
So if you had 0.5 doing (int) Math.random() would give you 0.
Now looking at your code, you'd have something like this
Assuming Math.random() gives 0.3, you'd have
((int)(0.3 * 15) == 1) which will be ((int)(4.5) == 1) now remember what casting to int does? throw out the decimal places. So we are left with if (4 == 1).
In this case the condition will be false so the code in the if won't run but there is a chance that you would have a number like 1.xx after multiplying.
The java.lang.Math.random() returns a double value with a positive
sign, greater than or equal to 0.0 and less than 1.0.
x * 15 = 1
x = 1/15
So X is a double value from interval 0-1. Everything is correct.
Related
How come? I thought that "+1" is the lowest number it can generate... This is the question:
"(int) Math.random()*(65535 + 1) returns a random number between:
Between 0 and 65535. <- answer
This is a question from a sololearn challenge.
The documentation of method Math.random() says:
Returns a double value with a positive sign, greater than or equal to 0.0 and less than 1.0.
It's obvious - mathematically expressed, the generated interval is <0, 1). It means, the generated number will never reach 1.0 but maximally a number a bit below (ex. 0.99). Since you multiply it with 65535, it will never reach 65535. That's why you have to add +1.
I recommend you to use the class Random and it's method nextInt(int bound) which does:
Returns a pseudorandom, uniformly distributed int value between 0 (inclusive) and the specified value (exclusive)
Therefore:
Random random = new Random();
int integer = random.nextInt(65536); // 65535 + 1 because the number is exclusive
The way you have the code right now:
(int) Math.random()*(65535 + 1)
You will always get 0.
The Math.random() method generates a number in the range [0, 1).
Returns a double value with a positive sign, greater than or equal to 0.0 and less than 1.0.
When you multiply that number by n, it has a range of [0, n). Casting it to int truncates any decimal portion of the number, making that number 0, and anything multiplied with 0 is 0. The cast occurs first because it's a higher precedence than multiplication.
Let's add parentheses so the cast occurs after the multiplication.
(int) (Math.random()*(65535 + 1))
When you multiply the truncated number by n, it has a range of [0, n). Casting it to int after the multiplication truncates any decimal portion of the number, making the range of integers 0 through (n - 1).
If you add 1 after multiplying and casting, then the lowest number it could generate would be 1. The range before adding would be 0 through 65534, after adding it would be 1 through 65535.
(int) (Math.random()*65535) + 1
How come? I thought that "+1" is the lowest number it can generate...
That is because the +1 was placed within the brackets. See below:
(int) Math.random()*(65535 + 1) //is equivalent to
(int) Math.random()*(65536) //which is equivalent to
(int) 0.0 to number < 1.0 *(65536) //which gives you a range of..
(int) (0 * 65536) to (0.999.. * 65536) //which gives you..
(int) 0 to 65535.34464.. //converted to int gives you
0 to 65535
If you want the minimum random number to be at least 1. Add it after the random operation is done:
(int) (Math.random()*65535) + 1
I am making a lottery type game and using Math.random() for the numbers. I want it to always print out what number you got in relation to 0 - 100 (so if Math.random outputted 0.03454 and the number to win was below 0.05, it would set the text of a label to 5). How would you make it round to just a 0.00 number?
Here is some of the code if you want to see what I mean.
public void lotterymath()
{
double x = Math.random();
System.out.println(x);
if (x <= 0.02)
output.setText("you win " + x);
else
output.setText( "you lost " + x);
}
I also have a button below that calls lotterymath() by the way :)
Edit: misread original post:
You will want to multiply by 100, and then cast to an int to truncate it, or Math.round it instead:
System.out.println(Math.round(x*100)); // rounds up or down
or
System.out.println((int) (x*100));
Original:
Use String.format(String, Object...):
System.out.println(String.format("%.2f", x));
The %.2f is a format string.
Have you tried
Math.round(x)
Checkout this link for the documentation: http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html#round(double)
EDIT:
I might not have fully understanded your question, but I think if you use
Math.round(Math.random*100)
You'll get a number between 0 and 100.
I prefer to use BigDecimal when dealing with floating point numbers
BigDecimal myRounded = new BigDeicmal(Math.random()).setScale(2, BigDecimal.ROUND_HALF_UP);
Since Math.random() returns a double between 0.0 to 1.0, you can just multiply the result with 100. So 0.0 * 100 = 0, 1.0 * 100 = 100, and everything in between will always be between 0 and 100.
Use Math.round() to get a full integer number. So if the random number is 0.03454, multiplied by 100 = 3.454. Round it to get 3.
correct:
int var = (int)Math.round(Math.random()*100)
INCORRECT:
int var = Math.round(Math.random()*100)
you need to downcast to integer before assign to integer variable in order to don't get an error like this:
error: incompatible types: possible lossy conversion from long to int
int var = Math.round( Math.random() * 3);
^
When you create the variable multiply it by 100 like so:
double a = Math.random()*100;
then when you have to print it put an (int) before the variable just like down here:
System.out.print((int)a);
Had a look around the questions on this site and could not quite find the answer I was looking for about type casting the Math.random() method from double to int.
My question is, why does Math.random only return a 0 without parentheses whereas it returns random numbers when it is contained within the parentheses?
The first part of code returns 0:
int number;
number = (int) Math.random() * 10;
System.out.println("\nThe random number is " + number);
This code works however:
int number;
number = (int) (Math.random() * 10);
System.out.println("\nThe random number is " + number);
It should be noted I have seen a few different pieces of code on typecasting whereby some programmers seem to use both ways of casting.
This code:
number = (int) Math.random() * 10;
first calculates this:
(int) Math.random()
Since Math.random() returns a number from 0 up to but not including 1, if you cast it to int, it will round down to 0. Then when you multiply 10 to 0 you get 0.
Math.random() returns a number from 0 to 1. You want to cast the result of (Math.random()*10) to int, not the number you get from Math.random itself.
Numbers get rounded down. Therefore, for example, 0.3, which you can get from Math.random, gets rounded to 0. Again, you want to round the result of 0.3 times 10, which is 3. The parenthesis is important.
How could I always round up a double to an int, and never round it down.
I know of Math.round(double), but I want it to always round up.
So if it was 3.2, it gets rounded to 4.
You can use Math.ceil() method.
See JavaDoc link: https://docs.oracle.com/javase/10/docs/api/java/lang/Math.html#ceil(double)
From the docs:
ceil
public static double ceil(double a)
Returns the smallest (closest to negative infinity) double value that is greater than or equal to the argument and is equal to a mathematical integer. Special cases:
If the argument value is already equal to a mathematical integer, then the result is the same as the argument.
If the argument is NaN or an infinity or positive zero or negative zero, then the result is the same as the argument.
If the argument value is less than zero but greater than -1.0, then the result is negative zero.
Note that the value of Math.ceil(x) is exactly the value of -Math.floor(-x).
Parameters:
a - a value.
Returns:
The smallest (closest to negative infinity) floating-point value that is greater than or equal to the argument and is equal to a mathematical integer.
In simple words,
Math.ceil will always round UP or as said above, in excess.
Math.round will round up or down depending on the decimals.
If the decimal is equal or higher than 5, then it's rounded up.
decimal => 5. (1,5 = 2)
If the decimal is less than 5, then it's rounded down.
decimal < 5. (1,45 = 1)
Examples of Math.ceil and Math.round:
The code Below would return:
Cost, without Ceil 2.2 and with Ceil 3 (int), 3.0 (double). If we round it: 2
int m2 = 2200;
double rate = 1000.0;
int costceil = (int)Math.ceil(m2/rate);
double costdouble = m2/rate;
double costdoubleceil = Math.ceil(m2/rate);
int costrounded = (int)Math.round(m2/rate);
System.out.println("Cost, without Ceil "+costdouble+" and with Ceil "+
costceil+"(int), "+costdoubleceil+"(double). If we round it: "+costrounded);
If we change the value of m2 to for example 2499, the result would be:
Cost, without Ceil 2.499 and with Ceil 3 (int), 3.0 (double). If we round it: 2
If we change the value of m2 to for example 2550, the result would be:
Cost, without Ceil 2.55 and with Ceil 3 (int), 3.0 (double). If we round it: 3
Hope it helps. (Information extracted from previous answers, i just wanted to make it clearer).
tl;dr
BigDecimal( "3.2" ).setScale( 0 , RoundingMode.CEILING )
4
BigDecimal
If you want accuracy rather than performance, avoid floating point technology. That means avoiding float, Float, double, Double. For accuracy, use BigDecimal class.
On a BigDecimal, set the scale, the number of digits to the right of the decimal place. If you want no decimal fraction, set scale to zero. And specify a rounding mode. To always round an fraction upwards, use RoundingMode.CEILING, documented as:
Rounding mode to round towards positive infinity. If the result is positive, behaves as for RoundingMode.UP; if negative, behaves as for RoundingMode.DOWN. Note that this rounding mode never decreases the calculated value. So for example, 1.1 becomes 2, and your 3.2 becomes 4.
BigDecimal bd = new BigDecimal( "3.2" ) ;
BigDecimal bdRounded = bd.setScale( 0 , RoundingMode.CEILING ) ;
String output = bdRounded.toString() ;
System.out.println( "bdRounded.toString(): " + bdRounded ) ; // 4
4
See this code run live at IdeOne.com.
private int roundUP(double d){
double dAbs = Math.abs(d);
int i = (int) dAbs;
double result = dAbs - (double) i;
if(result==0.0){
return (int) d;
}else{
return (int) d<0 ? -(i+1) : i+1;
}
}
Good job ! ;)
My method is relatively simple, hope it works for you.
In my case I have a row of objects that can only hold 3 items and I must adjust the number of rows I have to accommodate the items.
So I have some Double numberOfRows, I then use numberOfRows.intValue() to get an int value for numberOfRows.
if the int value I get is less than numberOfRows, I add 1 to numberOfRows to round it up, else the value I get from numberOfRows.intValue() is the answer I want.
I wrote this simple for loop to test it out:
for(int numberOfItems = 0; numberOfItems < 16; numberOfItems++) {
Double numberOfRows = numberOfItems / 3.0;
System.out.println("Number of rows are: " + numberOfRows);
System.out.println("Number of items are: " + numberOfItems);
if(numberOfRows.intValue() < numberOfRows) {
System.out.println("int number of rows are: " + (numberOfRows.intValue() + 1));
}
else {
System.out.println("int value of rows are: " + numberOfRows.intValue());
}
System.out.println();
System.out.println();
}
Short example without using Math.ceil().
public double roundUp(double d){
return d > (int)d ? (int)d + 1 : d;
}
Exaplanation:
Compare operand to rounded down operand using typecast, if greater return rounded down argument + 1 (means round up) else unchanged operand.
Example in Pseudocode
double x = 3.01
int roundDown = (int)x // roundDown = 3
if(x > roundDown) // 3.01 > 3
return roundDown + 1 // return 3.0 + 1.0 = 4.0
else
return x // x equals roundDown
Anyway you should use Math.ceil(). This is only meant to be a simple example of how you could do it by yourself.
Math.ceil did not work for me. It keeps rounding down when I cast back to long. Below is my hack:
long pages = (userCnt % size) == 0 ? (userCnt / size) : (userCnt / size) + 1;
Simply check if Even or Odd and if Odd, add 1 to the result.
Math.ceil() will give you the closest lowest value if you want it to be rounded to largest closest values you should use Math.floor()
int total = (int) Math.ceil(157/32);
Why does it still return 4? 157/32 = 4.90625, I need to round up, I've looked around and this seems to be the right method.
I tried total as double type, but get 4.0.
What am I doing wrong?
You are doing 157/32 which is dividing two integers with each other, which always result in a rounded down integer. Therefore the (int) Math.ceil(...) isn't doing anything. There are three possible solutions to achieve what you want. I recommend using either option 1 or option 2. Please do NOT use option 0.
Option 0
Convert a and b to a double, and you can use the division and Math.ceil as you wanted it to work. However I strongly discourage the use of this approach, because double division can be imprecise. To read more about imprecision of doubles see this question.
int n = (int) Math.ceil((double) a / b));
Option 1
int n = a / b + ((a % b == 0) ? 0 : 1);
You do a / b with always floor if a and b are both integers. Then you have an inline if-statement which checks whether or not you should ceil instead of floor. So +1 or +0, if there is a remainder with the division you need +1. a % b == 0 checks for the remainder.
Option 2
This option is very short, but maybe for some less intuitive. I think this less intuitive approach would be faster than the double division and comparison approach:
Please note that this doesn't work for b < 0.
int n = (a + b - 1) / b;
To reduce the chance of overflow you could use the following. However please note that it doesn't work for a = 0 and b < 1.
int n = (a - 1) / b + 1;
Explanation behind the "less intuitive approach"
Since dividing two integers in Java (and most other programming languages) will always floor the result. So:
int a, b;
int result = a/b (is the same as floor(a/b) )
But we don't want floor(a/b), but ceil(a/b), and using the definitions and plots from Wikipedia:
With these plots of the floor and ceil functions, you can see the relationship.
You can see that floor(x) <= ceil(x). We need floor(x + s) = ceil(x). So we need to find s. If we take 1/2 <= s < 1 it will be just right (try some numbers and you will see it does, I find it hard myself to prove this). And 1/2 <= (b-1) / b < 1, so
ceil(a/b) = floor(a/b + s)
= floor(a/b + (b-1)/b)
= floor( (a+b-1)/b) )
This is not a real proof, but I hope you're satisfied with it. If someone can explain it better I would appreciate it too. Maybe ask it on MathOverflow.
157/32 is int/int, which results in an int.
Try using the double literal - 157/32d, which is int/double, which results in a double.
157/32 is an integer division because all numerical literals are integers unless otherwise specified with a suffix (d for double l for long)
the division is rounded down (to 4) before it is converted to a double (4.0) which is then rounded up (to 4.0)
if you use a variables you can avoid that
double a1=157;
double a2=32;
int total = (int) Math.ceil(a1/a2);
int total = (int) Math.ceil((double)157/32);
Nobody has mentioned the most intuitive:
int x = (int) Math.round(Math.ceil((double) 157 / 32));
This solution fixes the double division imprecision.
In Java adding a .0 will make it a double...
int total = (int) Math.ceil(157.0 / 32.0);
When dividing two integers, e.g.,
int c = (int) a / (int) b;
the result is an int, the value of which is a divided by b, rounded toward zero. Because the result is already rounded, ceil() doesn't do anything. Note that this rounding is not the same as floor(), which rounds towards negative infinity. So, 3/2 equals 1 (and floor(1.5) equals 1.0, but (-3)/2 equals -1 (but floor(-1.5) equals -2.0).
This is significant because if a/b were always the same as floor(a / (double) b), then you could just implement ceil() of a/b as -( (-a) / b).
The suggestion of getting ceil(a/b) from
int n = (a + b - 1) / b;, which is equivalent to a / b + (b - 1) / b, or (a - 1) / b + 1
works because ceil(a/b) is always one greater than floor(a/b), except when a/b is a whole number. So, you want to bump it to (or past) the next whole number, unless a/b is a whole number. Adding 1 - 1 / b will do this. For whole numbers, it won't quite push them up to the next whole number. For everything else, it will.
Yikes. Hopefully that makes sense. I'm sure there's a more mathematically elegant way to explain it.
Also to convert a number from integer to real number you can add a dot:
int total = (int) Math.ceil(157/32.);
And the result of (157/32.) will be real too. ;)
int total = (int) Math.ceil( (double)157/ (double) 32);
Check the solution below for your question:
int total = (int) Math.ceil(157/32);
Here you should multiply Numerator with 1.0, then it will give your answer.
int total = (int) Math.ceil(157*1.0/32);
Use double to cast like
Math.ceil((double)value) or like
Math.ceil((double)value1/(double)value2);
Java provides only floor division / by default. But we can write ceiling in terms of floor. Let's see:
Any integer y can be written with the form y == q*k+r. According to the definition of floor division (here floor) which rounds off r,
floor(q*k+r, k) == q , where 0 ≤ r ≤ k-1
and of ceiling division (here ceil) which rounds up r₁,
ceil(q*k+r₁, k) == q+1 , where 1 ≤ r₁ ≤ k
where we can substitute r+1 for r₁:
ceil(q*k+r+1, k) == q+1 , where 0 ≤ r ≤ k-1
Then we substitute the first equation into the third for q getting
ceil(q*k+r+1, k) == floor(q*k+r, k) + 1 , where 0 ≤ r ≤ k-1
Finally, given any integer y where y = q*k+r+1 for some q,k,r, we have
ceil(y, k) == floor(y-1, k) + 1
And we are done. Hope this helps.
There are two methods by which you can round up your double value.
Math.ceil
Math.floor
If you want your answer 4.90625 as 4 then you should use Math.floor and if you want your answer 4.90625 as 5 then you can use Math.ceil
You can refer following code for that.
public class TestClass {
public static void main(String[] args) {
int floorValue = (int) Math.floor((double)157 / 32);
int ceilValue = (int) Math.ceil((double)157 / 32);
System.out.println("Floor: "+floorValue);
System.out.println("Ceil: "+ceilValue);
}
}
I know this is an old question but in my opinion, we have a better approach which is using BigDecimal to avoid precision loss. By the way, using this solution we have the possibility to use several rounding and scale strategies.
final var dividend = BigDecimal.valueOf(157);
final var divisor = BigDecimal.valueOf(32);
final var result = dividend.divide(divisor, RoundingMode.CEILING).intValue();
int total = (157-1)/32 + 1
or more general
(a-1)/b +1