I've been trying to make the unitTotal(double) into an integer by using the rounding method, then assigning the integer to the mark variable. I have been stuck on this question and I don't know what I'm doing wrong. If anyone can explain to me what I'm doing wrong it'd be appreciated. Thank you
public class GradeCalculator {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
double unitTotal;
int mark;
String grade;
System.out.println("Enter your unit total score");
unitTotal = sc.nextDouble();
Math.round(unitTotal);
mark = unitTotal;
You should assign the rounding result to the variable:
mark = (int) Math.round(unitTotal);
Do note that Math class suggests to round double to long. By casting to int you are potentially loosing precision.
You could use sc.nextFloat(); instead. Then you can use Math.round(float a) that returns int and assign it to mark:
mark = Math.round(sc.nextFloat());
If what you want is a method for rounding a double to the nearest whole number then I have an idea, though it's not using a library method.
public int round(double value) {
int cutDecimals = (int) value; // This cuts the decimals entirely, rounding down
double decimals = value - ((double) cutDecimals); // Gives only the decimals
if(decimals < 0.5) return cutDecimals; // If the decimals is less than 0.5 we return the rounded down number
else return cutDecimals + 1; // If the decimals is over 0.5 we round up
}
According to Docs, Math.round method returns long when passing value is double and returns int when passing value is float.
Change type of mark to long or you need to convert long into int manually. Keep in mind that it could throw an exception if return value is more than Integer.MAX_VALUE.
Also, you need to store return value into variable.
Math.round(unitTotal);
replace with
mark = Math.round(unitTotal);
HTH.
Related
I've got a really annoying task to do, and stuck with it.
So: I need to write a function which gives back the value of a floating number after the decimal.
For example: the param would be:5.456-> and the returning value should be:456.
I can not use String (of course this would be easy this way).
Do you have any suggestions?
It requires some steps to do it with primitives like float or double. If you were allowed to use BigDecimal, this would just be one line of code.
Given double d = 5.456;
first, cut off the part before the floating point.
do this by int full = (int)d; which will be 5
the subtract full from it: d-full will now be only the part after the point, so .456
now use a loop to multiply the value by 10 until the "after the point" part is 0.
The special thing here is that when you use double, you have floating point precision issues. That means that d will have the value 0.4560000000000004 in between. To solve that, let's introduce an epsilon.
The full code looks like this:
private static final double EPS = 1e-5;
public static void main(String[] args) {
double d = 5.456;
System.out.println(afterDot(d));
}
private static int afterDot(double d) {
d = getDecimals(d);
while(getDecimals(d) > EPS){ //decimals will likely never be 0 because of precision, so compare with a really small EPS instead of 0
d *= 10;
}
//cast the result to an int to cut off the double precision issues
return (int)d;
}
private static double getDecimals(double d) {
int full = (int) d;
d = d-full;
return d;
}
This prints 456. I am very sure this can be optimized somehow, but it's a working first draft.
What you want is the remainder, multiplied by 10 until the remainder is 0. Using BigDecimal to prevent rounding issues that looks like this:
final BigDecimal input = new BigDecimal("5.456");
BigDecimal x = input.remainder(BigDecimal.ONE);
while (x.remainder(BigDecimal.ONE).compareTo(BigDecimal.ZERO) > 0) {
x = x.multiply(new BigDecimal(10));
}
System.out.println(x.longValue());
Here are two ways that don't adjust for floating point anomalies.
double s = 5.456;
System.out.println(s%1);
or
System.out.println(s-(int)s);
both print
0.4560000000000004
Or use BigDecimal and adjust the scale and subtract the integer value.
System.out.println(BigDecimal.valueOf(s)
.setScale(3)
.subtract(BigDecimal.valueOf((int)s)));
prints
.456
I have the following situation, when I give e.g. one number 10.55000, this number is rounded correctly to 10.55, then after adding 10.5501, everything is also fine because I get 21.1001, but in the next stage, when I add the number 10.55 I get the following result: 31.6501000001, and I should receive 31.6501. What should I do to get in stage 3 of 31.6501 instead of 31.6501000001.
This is my Numbers class:
class Numbers {
private double result;
private double currentNumber;
public void calculateResult (double number) {
currentNumber = number;
result += currentNumber ;
}
public String getResult() {
DecimalFormat decimalFormat = new DecimalFormat("#.##########");
decimalFormat.setRoundingMode(RoundingMode.CEILING);
return decimalFormat.format(result);
}
}
This is my main method:
Numbers numbers = new Numbers();
numbers.calculateResult(10.55000);
System.out.println(numbers.getResult());
numbers.calculateResult(10.5501);
System.out.println(numbers.getResult());
numbers.calculateResult(10.55);
System.out.println(numbers.getResult());
As already stated floating point numbers such as float and double suffer from precision issues and those can add up with each calculation. For more exact calculations you should use BigDecimal instead.
Here's an example of your class that keeps the same method signatures but uses BigDecimal internally:
class Numbers {
private BigDecimal result = BigDecimal.ZERO;
private BigDecimal currentNumber;
public void calculateResult( double number ) {
currentNumber = BigDecimal.valueOf( number );
result = result.add( currentNumber );
}
public String getResult() {
//no rounding here because your question doesn't involve any actual rounding
return result.toString();
}
}
Output for your test calculations:
10.55
21.1001
31.6501
Note that the example above doesn't actually do any rounding, i.e. if you add 0.000001 then this will get reflected in the resulting value.
If you need to round to let's say 4 significant decimal places (0 to 4 at most) you could use this instead:
return result.setScale( 4, RoundingMode.CEILING ).stripTrailingZeros().toString();
You must set your format appropriately. Use new DecimalFormat("#.####") instead of new DecimalFormat("#.##########") because you only want to see 4 digits after the dot.
This will give you
10,55
21,1001
31,6502
If you need higher precision you need to use a different data type for example BigDecimal
Initializing a double variable with a value greater than 1E309 gives an error during compilation.
However, taking that value as an input does not produce any error. In fact, printing the double variable gives the String "Infinity".
Why does this happen?
import java.util.Scanner;
public class BigDouble {
public static void main(String[] args) {
double number;
Scanner keyboard = new Scanner(System.in);
System.out.print("Enter a number: ");
number = keyboard.nextDouble();
System.out.println(number);
}
}
You didn't get any errors because nextDouble() parses a Double, not a double. Double as a wrapper class, has several useful constants:
public static final double POSITIVE_INFINITY = 1.0 / 0.0;
public static final double NEGATIVE_INFINITY = -1.0 / 0.0;
public static final double NaN = 0.0d / 0.0;
Inside, nextDouble() uses Double.parseDouble(String) to provide a result regardless of the range the inputted number is in.
public double nextDouble() {
...
try {
return Double.parseDouble(processFloatToken(next(floatPattern())));
} catch (NumberFormatException nfe) {
...
}
}
If the number is out of the double range, you will be given either POSITIVE_INFINITY or NEGATIVE_INFINITY.
"NaN" -> Double.parseDouble("NaN") -> Double.NaN -> NaN
"1E6000" -> Double.parseDouble("1E6000") -> Double.POSITIVE_INFINITY -> Infinity
When you say, "Initializing a double variable with a value greater than 1E309", you probably mean like:
double number = 1E6000;
Here, "1E6000" appearing as-is, is called a "literal" value. You are writing a program, and asking it that it literally uses this value as a double.
Which is impossible as this value is too large. So there is no sense allowing you to do that. Instead, use a value that can actually be represented, or if you want infinity, use constant Double.POSITIVE_INFINITY instead. Rejecting the literal 1E6000 is not taking away any options from you.
However, when you're not dealing with a literal value, but the result of some computing, then the common contract of floating-point numbers, is that if the value computed is too big to be represented, you provide infinity to represent it. Not an error.
Here the programmer has no way to predict that the user will type in a number too large to be represented exactly. There is no better alternative to propose, than to represent the value computed as a result, as infinity.
I am new to Java and I would like to know why when you have double 10/4 you get 2? Does double always have to have decimals in order to get the right answer? Thanks.
public class Super {
public static void main(String[] args){
double x = 10/4;
System.out.println(x);
}
}
You are performing integer division before assigning the result. Integer division results in an int, the truncated result 2. To force floating point calculation and get 2.5, use double literals:
double x = 10.0 / 4.0;
or cast one to a double:
double x = (double) 10 / 4;
You are dividing with integers. You can declare those as doubles the following way (or use f for floats):
double x = 10d/4d;
System.out.println(x);
Integer division. Even though you're assigning the result to a double, you're still dividing two integers (10 and 4) so you get an integer result (floor of the actual result).
You can fix this by having one or both operands be a floating point value, for example like this:
double x = 10.0/4;
or by using type casting:
double x = (double)10/4;
Replace it by:
double x = 10.0/4.0;
Double always takes in a decimal. So it would have to be
public class Super {
public static void main(String[] args){
double x = 10.0/4.0;
System.out.println(x);
}
}
For double you need to use the following
10d/4d
Then the output is going to be 2.5 Otherwise you are just gonna end up diving two integers
The right side ofter the '=' is an integer expression, which gets converted to double only after it's calculated. So it calculates 10/4 as an integer, 2, and then converts that number to double. If you want it as a double from the beginning you have to write
double x = 10.0 / 4.0;
Only numbers that cannot be read as integer will be treated as double. Or even simpler
double x = 2.5; // :-)
I have declared a variable as double. I wanted to do division of two integer and assign the output to that double variable.
But its not considering the values like 0.1 to 0.9. Only when the no is whole number like 4.0 its returning the answer
public static void main(String[] args) throws Exception
{
double itf=0;
a=4100;
b=6076
itf=a/b;
System.out.println("itf:"+itf)
}
Output is itf: 0.0
Pls help..
Most likely the variables a and b are defined as int , which will result in integer division result as 0 and when assigned to double it becomes 0.0. If you define a,b and itf as double then the result should be
0.6747860434496379
instead of
0.0
Try this code:
public static void main(String[] args) throws Exception {
double itf = 0;
double a = 4100;
double b = 6076;
itf = a / b;
System.out.println("itf:" + itf);
}
a and b are both integers, so the result of a/b is also an integer, which is then cast to a double to be stored in itf. To get the correct result, you could either define a and b as doubles, or you could cast at least one of them to double. For instance:
itf = (double)a/b;
Declare a or b as double.
OR
Cast the operation.
itf = (double)(a/b)
OR Cast one of the integers.
itf = ((double)a)/b
OR multiply with 1.0, which is double.
itf = (1.0*a)/b
The reason for your result is that you are using integer division, then assign the result to a double value. This is your code unrolled:
int a = 4100;
int b = 6076;
int temp = a / b;
double itf = temp;
If you want to explicitly use floating point division, you need to tell the compiler that you do by casting at least one (or all to be sure) member of that operation to double or float. Example:
itf = (double)a / (double)b;
Use the foloving cast to at least one operand to double
itf=((double)a)/b;
or
itf=a/((double)b);
double itf = ((double) a / (double) b);