I am going through the following code in Java:
public float a1 = 0.10f;
int Increments;
if(TotalTime > 0)
{
Increments = (int) ceil(TotalTime / Increment1);
amount = round(Increments * a1, 4);
}
Where,
TotalTime and Increment1 are integers
My questions is, Why do we need to typecast to integer just before ceil as done in the following line of code above?
Increments = (int) ceil(TotalTime / Increment1);
Because Math.ceil (I suppose it's a static import there) returns a double. As you make a restriction of the converted value (by converting to a less precise type), you need to do the conversion explicitly.
Also, please note that the argument you pass to ceil is the ratio of two integers, which is also an integer. So you're in danger of losing precision. Moreover, applying ceil to an integer is redundant, as it will return that integer itself. And the last remark: ceil expects a double as its argument. In this case, you pass an int, but the conversion is done implicitly, because it is done from a less precise to a more precise type.
The reason is that Math.ceil returns a double. You cannot implicitly cast from a double to an int. Trying to compile this:
double d = 2.1;
int i = d;
Gives you:
dur.java:4: possible loss of precision
found : double
required: int
int i = d;
^
1 error
As the error message states, the reason is that you might lose precision, so the compiler wants to be sure that you really want to allow this loss. You do this by making the cast explicit:
int i = (int)d;
Note that even so, your code won't do what you expect.
int i = 10;
int j = 3;
int k = (int)Math.ceil(i/j);
System.out.println(k); //outputs '3'
The reason is that i / j performs integer division if both i and j are integers, which rounds down. i / j is already 3, and all Math.ceil does is return 3.0, which then again gets casted to 3. You want to do floating point division instead, which is done when one or both of i and j are floating point types. You can achieve this by casting one of the integers to a double before doing the division:
int i = 10;
int j = 3;
int k = (int)Math.ceil((double)i/j);
System.out.println(k); //outputs '4'
Related
So I just wanted to screw around to see if I can make it so I can calculate E, but instead have it so I can have dynamic degrees of precision. While I did technically accomplish it, no matter what int i put in for the variable PRECISION, the last few numbers are always different from what the actual value of E is suppose to be. I'm not entirely sure why, but help would be appreciated.
import java.math.BigDecimal; //To use for calculating E
public class ComputeE {
public static double calcDenominator(int n)
{
double denominator = 1.0; //Start the BigInt with 1
for(int i = 1; i < n; i++) // Run n-1 amount of times
{
denominator = denominator * i; // Multiply BigInteger by the BigInteger obtained with the int value i
}
return denominator;
}
public static void main(String[] args) {
BigDecimal e = new BigDecimal(0.0);
int PRECISION = 15;
int iterations = 0;
for(int i = 0; i < PRECISION; i++)
{
iterations++;
BigDecimal numerator = new BigDecimal(1.0); // to divide, we need two BigDecimals, the numerator is 1
BigDecimal factorial = new BigDecimal(calcDenominator(i)); // the denominator is i! which we get from calling the factorial method
factorial = numerator.divide(factorial, PRECISION, BigDecimal.ROUND_UNNECESSARY); // compute 1/i!, note divide is overloaded, this version is used to
// ensure a limit to the iterations when division is limitless like 1/3
e = e.add(factorial); // add the latest 1/i! to e
}
System.out.println("Computed value of e : " + e);
System.out.println("Expected value of e : " + Math.E);
}
}
Rounding is necessary here. Use something like HALF_EVEN. Even better, use the enum value RoundingMode.HALF_EVEN, because the integer constants for rounding mode are deprecated.
In calcDenominator, change your for loop condition to i <= n, or else you'll add 1 one too many times in main and you'll get a value that's 1 too high.
You can use BigDecimal.ONE to initialize numerator. This doesn't affect the result, but why create an unnecessary object? Same comment on the initialization of e, except with BigDecimal.ZERO.
You are using the first PRECISION terms of an infinite series (Maclaurin Series) that approximates e, an irrational number. There is an error term when you cut off the for loop, and that is expected mathematically. With the above changes, and bumping PRECISION to 50, I get the following, which looks sufficiently precise.
Computed value of e : 2.71828182845904523536028747135266249775496954201584
Expected value of e : 2.718281828459045
It is precise, despite using the double constructor for BigDecimal because the significant digits for a double start with the first non-zero bit, so even if you're calculating 1/n! for large n, the significant digits are good enough for adding to the existing approximation for e.
I have a small doubt that I couldn't get around with that is I have a double variable which stores double value but I want it to print 0 instead of 0.0 when it has no data but whatever I try I couldn't make it work
for example:
double a = 0;
System.out.println(a);
should give me 0 instead of 0.0
I know it's a silly question but can anyone point me in the right direction,
thank you in advance.
Use some method as shown below:
double a = 0.0;
System.out.println(formatA(a));
static String formatA(double a) {
if (a == 0.0)
return "0";
else
return String.valueOf(a);
}
You can cast type of variable 'a' to an integer.
double a = 0;
System.out.println((int)a);
man, double a = 0; is a decimal type. you'd make:
change the type of the value
int a = 0
Or, also you can cast the value.
System.out.println((int) a);
If you don't want to see the fractional part of the double value, you can cast it into long value.
Note, it's not a good idea to cast it into "int" value, because max "double" value is greater than max "int" value.
double a = 0;
System.out.println((long)a);
Let's say I have a short[] thisArray in JAVA, and I need to calculate the average based on the amount of elements in this array. But apparently, .length will return a int number to represent the length of thisArray.
I cannot convert it into int Array or int, since it is not allowed to convert int back to short. I do need to have a short result and store back into another short[][].
How to avoid this classic error:
error: incompatible types: possible lossy conversion from int to short
short result = sum / thisArray.length;
public static short getSum(short[] sumArray) {
short sum = 0;
for(short i : sumArray) {
sum += i;
}
return sum;
}
sum = getSum(thisArray);
short result = sum / thisArray.length;
If you know for sure the average can fit into a short variable, you just have to cast the result:
short result = (short)(sum / thisArray.length);
I'd also change sum to int, to reduce the risk of overflow (which may occur if the sum is larger than 32767).
To summarize:
public static int getSum(short[] sumArray) {
int sum = 0;
for(short i : sumArray) {
sum += i;
}
return sum;
}
...
int sum = getSum(thisArray);
short result = (short) (sum / thisArray.length);
You need to explicitly cast the result
short result = (short)( sum / thisArray.length );
The compiler is protecting you from losing data when you assign an int value to a short variable. Providing the cast is the usual way of telling the compiler that you know what you're doing, and this operation is OK.
I'm making a simple calculator (I'm a beginner), and I was wondering why when I divide 1 by 4, I get 0. I know it has something to do with the type of number. Here is my code:
private static void calc(int a, int b,String op){
if (op.equals("add")){
double ans = a+b;
System.out.println(ans);
}
if(op.equals("subtract")){
double ans=a-b;
System.out.println(ans);
}
if(op.equals("multiply")){
double ans=a*b;
System.out.println(ans);
}
if(op.equals("divide")){
double ans=a/b;
System.out.println(ans);
}
}
I can't get my variable (ans) to have more than one decimal spot. And when the answer requires one (like 1/4), it just returns 0.
Help please.
You need to divide on a double since all your result values in double.
private static void calc(int a, double b,String op){
}
Or simply :
if(op.equals("divide")){
double ans=(double)a/b;
System.out.println(ans);
}
Although the other comments and answers are correct, they do not give enough detail (IMO).
Although ans is a double, the value of the right side of the equation is still an int.
double ans = a / b;
// equiv to:
// double ans = (double)(a / b);
So when you evaluate this you get:
double ans = (double)(1/4);
= (double)(0);
= 0.0d;
To get around this, you will need to cast one or both of the operands to a double.
double ans = ( (double) a ) / ( (double) b );
= ( (double) 1 ) / ( (double) 4 );
= 1.0d / 4.0d;
~= 0.25d;
Also note with regards to #Salah's answer that the cast from integer to double has just been moved. Since you can implicitly convert an int to a double, calling the function with an integer (such as the literal 1) will automatically convert the integer to a double. However, you may not want to allow non-integral numbers to be passed to your function, and if so, then this solution would not be correct.
Will a double equal to an integer always cast to that integer (assuming the double is not one that causes an overflow). Example: Math.ceil() will return a double that is equal to an integer. Assuming no overflow, will it always cast to the same integer that it is supposedly equal to?
If not, how can I round up a double to an int or long?
Since Java types are fixed and Java doubles have a 52 bit mantissa, they can (with ease) represent a 32-bit Java int without rounding.
Yes, it will convert exactly. This is described in Section 5.1.3 of the JLS, which mentions
Otherwise, if the floating-point number is not an infinity, the
floating-point value is rounded to an integer value V, rounding toward
zero using IEEE 754 round-toward-zero mode...
Since your double exactly equals the int, the "rounded" value is just the exact same value, but you can read the spec for details.
All possible int values can be represented by a double without error. The simplest way to round up is to use Math.ceil() e.g.
double d =
long l = (long) Math.ceil(d); // note: could overflow.
Empirically, the answer seems to be yes - note that it also works with i2 = (int) d;.
public static void main(String[] args) {
for (int i = Integer.MIN_VALUE + 1; i < Integer.MAX_VALUE; i++) {
double d = i;
int i2 = (int) Math.ceil(d);
if (i != i2) {
System.out.println("i=" + i + " and i2=" + i2); //Never executed
}
}
}
I believe so, but you might test it yourself:
public static void main(String... args) throws Exception {
int interactions = Integer.MAX_VALUE;
int i = Integer.MIN_VALUE;
double d = Integer.MIN_VALUE;
long init = System.currentTimeMillis();
for (; i < interactions; i++, d++)
if (!(i == (int) Math.ceil(d)))
throw new Exception("something went wrong with i=" + i + " and d=" + d + ", Math.ceil(d)="+Math.ceil(d));
System.out.println("Finished in: "+(System.currentTimeMillis() - init)+"ms");
}