This question already has answers here:
Is floating point math broken?
(31 answers)
How to round a number to n decimal places in Java
(39 answers)
Closed 10 months ago.
I've used these posts as reference:
How to round a number to n decimal places in Java
round up to 2 decimal places in java? [duplicate]
After reading through the solutions to these question, I'm still having trouble rounding up to the hundredths place.
Here are what I've tried along with their outputs:
BigDecimal
import java.math.BigDecimal;
import java.math.RoundingMode;
public class RaceCarThread extends Thread {
private static boolean raceNow = false;
private int iterations;
private double lapsCompleted;
private boolean crash;
private int nbrOfCrashes;
// Default constructor
public RaceCarThread() {
super();
}
// Constructor for custom name
public RaceCarThread(String name) {
super(name);
raceNow = true;
lapsCompleted = 0;
crash = false;
nbrOfCrashes = 0;
}
public void run() {
while (!(lapsCompleted >= 17)) {
double randomNum = Math.random();
BigDecimal bd = new BigDecimal(randomNum).setScale(2, RoundingMode.HALF_EVEN);
randomNum = bd.doubleValue();
lapsCompleted = lapsCompleted + randomNum;
System.out.println(lapsCompleted);
}
}
}
10.31
10.5
11.13
11.850000000000001
12.810000000000002
13.570000000000002
14.200000000000003
15.080000000000004
15.800000000000004
16.200000000000003
16.790000000000003
17.430000000000003
Math.round(randomNum*100d) / 100d
public class RaceCarThread extends Thread {
private static boolean raceNow = false;
private int iterations;
private double lapsCompleted;
private boolean crash;
private int nbrOfCrashes;
// Default constructor
public RaceCarThread() {
super();
}
// Constructor for custom name
public RaceCarThread(String name) {
super(name);
raceNow = true;
lapsCompleted = 0;
crash = false;
nbrOfCrashes = 0;
}
public void run() {
while (!(lapsCompleted >= 17)) {
double randomNum = Math.random();
lapsCompleted = lapsCompleted + (Math.round(randomNum * 100d) / 100d);
System.out.println(lapsCompleted);
}
}
}
11.020000000000003
11.730000000000004
12.720000000000004
13.430000000000003
13.930000000000003
14.020000000000003
14.300000000000002
15.210000000000003
15.250000000000002
15.500000000000002
16.32
17.080000000000002
I'm unable to use DecimalFormat due to using the number in calculations.
Edit: The System.out.println(lapsCompleted) is just for checking the values and will be removed once I fix the decimals
If you're going to do calculations with your decimal values, you really need to use BigDecimal throughout. Never trust double or float to give accurate answers to calculations involving decimal values.
Also, when you create a BigDecimal from a double, don't use new BigDecimal(yourDouble), because that just puts the floating point error that's already in your double into the BigDecimal. It's generally much better to use BigDecimal.valueOf(yourDouble), which gives you the decimal value with the least number of decimal places that your double is close enough to. That sounds bad, but it's actually good, because you typically get the value that was used to create the double initially.
For example,
System.out.println(new BigDecimal(0.1)); // prints 0.1000000000000000055511151231257827021181583404541015625
System.out.println(BigDecimal.valueOf(0.1)); // prints 0.1
This question already has an answer here:
What does "possible lossy conversion" mean and how do I fix it?
(1 answer)
Closed 4 years ago.
I'm creating a program that stores doubles in an array and then stores each array in an ArrayList then calculates the average from that ArrayList, but I keep getting a "possible lossy conversion from double to int." in line 5.
I'm new to java so I might be overseeing a simple fix.
public static double calculateAll(List<double[]> allNumbers) {
double average = 0.0;
double total = 0.0;
for(int i = 0; i < allNumbers.size(); i++) {
total += allNumbers.get(i);
}
average = total/allNumbers.size();
return average;
}
I am not sure what you are asking in the question, but I think this is what you are looking for.
public static double calculateAll(List<Double> allNumbers) {
double average;
double total = 0.0;
for (Double allNumber : allNumbers) {
total += allNumber;
}
average = total / allNumbers.size();
return average;
}
You were storing an Array Inside a Collection. So I have changed that to Double note that double is native while Double isn't. You can't have double inside a Collection. and then I have converted the for loop into a foreach loop
Here is how you can call this code.
public static void main(String[] args) {
List<Double> doubles = new ArrayList<>();
doubles.add(0.1);
doubles.add(4.1);
double wat = calculateAll(doubles);
System.out.println(wat);
}
So lets take a note of all the changes we have done.
List<double[]> has been replaced with List<Double>.
List now holds items of instance Double
for(int i = 0; i < allNumbers.size(); i++) was changed to for (Double allNumber : allNumbers) this is just a basic for-each loop.
Honestly I would just use java 8 for this, We can do this in 1 line!
public static double calculateAll(List<Double> allNumbers) {
return allNumbers.stream().mapToDouble(e -> e / allNumbers.size()).sum();
}
I have a formula to evaluate
((x+y-1)*(x+y-2))/2 + x
and get the string representation of it.
So in Java 1.7 I write
public static void main(String[] args)
{
int x = 99999;
int y = 99999;
int answer = ((x+y-1)*(x+y-2))/2 + x;
String s = Integer.toString(answer);
System.out.println(s);
}
and in Python 2.7
def answer(x, y):
z = ((x+y-1)*(x+y-2))/2 + x
return str(z);
print(answer(99999,99999))
Java gave me the out put of 672047173 while Python gave me 19999400005 and seems the value from Python is correct. What is the reason behind this difference.
19999400005 is a too large value for int variables, so the Java calculations would overflow.
Use long variables instead:
public static void main(String[] args)
{
long x = 99999;
long y = 99999;
long answer = ((x+y-1)*(x+y-2))/2 + x;
String s = Long.toString(answer);
System.out.println(s);
}
Output is:
19999400005
Also note that you can print answer directly and don't have to convert it to String explicitly:
System.out.println(answer);
Because integer range in java is minimum -2,147,483,648 and a maximum value of 2,147,483,647.
int answer = ((x+y-1)*(x+y-2))/2 + x;
In this line you are assigning higher range value to integer. It causes integer overflow on the arithmetic operation. So that is why you are getting incorrect value to get correct value you have to use Long data type.
public static void main(String[] args)
{
int x = 99999;
int y = 99999;
long answer = (((x+y-1)*1l)*((x+y-2)*1l))/2 + x;
String s = Long.toString(answer);
System.out.println(s);
}
This question already has answers here:
Addition for BigDecimal
(12 answers)
Closed 8 years ago.
class Point {
BigDecimal x;
BigDecimal y;
Point(double px, double py) {
x = new BigDecimal(px);
y = new BigDecimal(py);
}
void addFiveToCoordinate(String what) {
if (what.equals("x")) {
BigDecimal z = new BigDecimal(5);
x.add(z);
}
}
void show() {
System.out.print("\nx: " + getX() + "\ny: " + getY());
}
public BigDecimal getX() {
return x;
}
public BigDecimal getY() {
return y;
}
public static void main(String[] args) {
Point p = new Point(1.0, 1.0);
p.addFiveToCoordinate("x");
p.show();
}
}
Ok, I would like to add 2 BigDecimal values. I'm using constructor with doubles(cause I think that it's possible - there is a option in documentation). If I use it in main class, I get this:
x: 1
y: 1
When I use System.out.print to show my z variable i get this:
z: 5
BigDecimal is immutable. Every operation returns a new instance containing the result of the operation:
BigDecimal sum = x.add(y);
If you want x to change, you thus have to do
x = x.add(y);
Reading the javadoc really helps understanding how a class and its methods work.
Perhaps this is what you prefer:
BigDecimal z = new BigDecimal(5).add(x);
Every operation of BigDecimal returns a new BigDecimal but not change the current instance.
Say I have the following three constants:
final static int MY_INT1 = 25;
final static int MY_INT2 = -10;
final static double MY_DOUBLE1 = 15.5;
I want to take the three of them and use Math.max() to find the max of the three but if I pass in more then two values then it gives me an error. For instance:
// this gives me an error
double maxOfNums = Math.max(MY_INT1, MY_INT2, MY_DOUBLE2);
Please let me know what I'm doing wrong.
Math.max only takes two arguments. If you want the maximum of three, use Math.max(MY_INT1, Math.max(MY_INT2, MY_DOUBLE2)).
you can use this:
Collections.max(Arrays.asList(1,2,3,4));
or create a function
public static int max(Integer... vals) {
return Collections.max(Arrays.asList(vals));
}
If possible, use NumberUtils in Apache Commons Lang - plenty of great utilities there.
https://commons.apache.org/proper/commons-lang/javadocs/api-3.1/org/apache/commons/lang3/math/NumberUtils.html#max(int[])
NumberUtils.max(int[])
Math.max only takes two arguments, no more and no less.
Another different solution to the already posted answers would be using DoubleStream.of:
double max = DoubleStream.of(firstValue, secondValue, thirdValue)
.max()
.getAsDouble();
Without using third party libraries, calling the same method more than once or creating an array, you can find the maximum of an arbitrary number of doubles like so
public static double max(double... n) {
int i = 0;
double max = n[i];
while (++i < n.length)
if (n[i] > max)
max = n[i];
return max;
}
In your example, max could be used like this
final static int MY_INT1 = 25;
final static int MY_INT2 = -10;
final static double MY_DOUBLE1 = 15.5;
public static void main(String[] args) {
double maxOfNums = max(MY_INT1, MY_INT2, MY_DOUBLE1);
}
Java 8 way. Works for multiple parameters:
Stream.of(first, second, third).max(Integer::compareTo).get()
I have a very simple idea:
int smallest = Math.min(a, Math.min(b, Math.min(c, d)));
Of course, if you have 1000 numbers, it's unusable, but if you have 3 or 4 numbers, its easy and fast.
Regards,
Norbert
Like mentioned before, Math.max() only takes two arguments. It's not exactly compatible with your current syntax but you could try Collections.max().
If you don't like that you can always create your own method for it...
public class test {
final static int MY_INT1 = 25;
final static int MY_INT2 = -10;
final static double MY_DOUBLE1 = 15.5;
public static void main(String args[]) {
double maxOfNums = multiMax(MY_INT1, MY_INT2, MY_DOUBLE1);
}
public static Object multiMax(Object... values) {
Object returnValue = null;
for (Object value : values)
returnValue = (returnValue != null) ? ((((value instanceof Integer) ? (Integer) value
: (value instanceof Double) ? (Double) value
: (Float) value) > ((returnValue instanceof Integer) ? (Integer) returnValue
: (returnValue instanceof Double) ? (Double) returnValue
: (Float) returnValue)) ? value : returnValue)
: value;
return returnValue;
}
}
This will take any number of mixed numeric arguments (Integer, Double and Float) but the return value is an Object so you would have to cast it to Integer, Double or Float.
It might also be throwing an error since there is no such thing as "MY_DOUBLE2".
int first = 3;
int mid = 4;
int last = 6;
//checks for the largest number using the Math.max(a,b) method
//for the second argument (b) you just use the same method to check which //value is greater between the second and the third
int largest = Math.max(first, Math.max(last, mid));
You can do like this:
public static void main(String[] args) {
int x=2 , y=7, z=14;
int max1= Math.max(x,y);
System.out.println("Max value is: "+ Math.max(max1, z));
}
if you want to do a simple, it will be like this
// Fig. 6.3: MaximumFinder.java
// Programmer-declared method maximum with three double parameters.
import java.util.Scanner;
public class MaximumFinder
{
// obtain three floating-point values and locate the maximum value
public static void main(String[] args)
{
// create Scanner for input from command window
Scanner input = new Scanner(System.in);
// prompt for and input three floating-point values
System.out.print(
"Enter three floating-point values separated by spaces: ");
double number1 = input.nextDouble(); // read first double
double number2 = input.nextDouble(); // read second double
double number3 = input.nextDouble(); // read third double
// determine the maximum value
double result = maximum(number1, number2, number3);
// display maximum value
System.out.println("Maximum is: " + result);
}
// returns the maximum of its three double parameters
public static double maximum(double x, double y, double z)
{
double maximumValue = x; // assume x is the largest to start
// determine whether y is greater than maximumValue
if (y > maximumValue)
maximumValue = y;
// determine whether z is greater than maximumValue
if (z > maximumValue)
maximumValue = z;
return maximumValue;
}
} // end class MaximumFinder
and the output will be something like this
Enter three floating-point values separated by spaces: 9.35 2.74 5.1
Maximum is: 9.35
References Java™ How To Program (Early Objects), Tenth Edition
Simple way without methods
int x = 1, y = 2, z = 3;
int biggest = x;
if (y > biggest) {
biggest = y;
}
if (z > biggest) {
biggest = z;
}
System.out.println(biggest);
// System.out.println(Math.max(Math.max(x,y),z));