So I need to calculate a value.
The input I get is this:
a is seed/m2. The value might a for example 56 but it might be 56.7 also.
b is in g's. for instance 600g
c is % value, might be 90.6 also
d is % value, might be 90.6 also
The result I get should be as kg/ha
Regular int does not cut it. The value of (56 * 600 / 100 / 100) / 100
will be 0.0336. I could multiply it with 10000 but I would lose the precision.
I also tried BigDecimal for this but it gave me a ArithmeticException: “Non-terminating decimal expansion; no exact representable decimal result” when I changed the values of my % variables to something else than 100.
What would be the best option to go with this? The calculation was easy to do in exel as it knew how to convert each value automatically, but doing it in Java code is another thing.
My solutions:
int version:
int a = Integer.decode(germinativeSeed.getText().toString());
int b = Integer.decode(seedMass.getText().toString());
int c = Integer.decode(clean.getText().toString());
int d = Integer.decode(germinative.getText().toString());
int result2 = ( a * b / c / d) / 100;
result is 0
BigDecimal solution:
BigDecimal result2;
BigDecimal a = new BigDecimal(germinativeSeed.getText().toString());
BigDecimal b = new BigDecimal(seedMass.getText().toString());
BigDecimal c;
BigDecimal d;
if (clean.getText().toString().equals("")) {
c = new BigDecimal("100");
} else {
c = new BigDecimal(clean.getText().toString());
}
if (germinative.getText().toString().equals("")) {
d = new BigDecimal("100");
} else {
d = new BigDecimal(germinative.getText().toString());
}
BigDecimal hundred = new BigDecimal("100");
BigDecimal test = new BigDecimal("10000");
result2 = a.multiply(b);
result2 = result2.divide(c, 2, RoundingMode.HALF_UP);
result2 = result2.divide(d, 2, RoundingMode.HALF_UP);
result2 = result2.divide(hundred, 2, RoundingMode.HALF_UP);
result2 = result2.multiply(test);
Result is correct with this only if % values are 100%.
double seed = (double) seedInput;
double m2 = (double) m2Input;
double b = (double) bInput; // unit 'g' is not relevant
double c = (double) cInput;
double d = (double) dInput;
double a = seed / m2;
int result2 = ( a * b / c / d) / 100.0;
So I converted everything to double so you won't have problems with implicit conversions to int.
Your problem comes when you have rational numbers like 1/3, this cannot be represented in a bigdecimal, as it has an infinite representation.
If you really need very big precision you should crate a new bigrational class, where you would store a nominator and denominator, and calculate with them. The code would be much mode complicated.
If you don't need that go for doubles.
Try using float or double (preferred double because of the precision).
I have read this question Round a double to 2 decimal places It shows how to round number. What I want is just simple formatting, printing only two decimal places.
What I have and what I tried:
double res = 24.695999999999998;
DecimalFormat df = new DecimalFormat("####0.00");
System.out.println("Value: " + df.format(res)); //prints 24.70 and I want 24.69
System.out.println("Total: " + String.format( "%.2f", res )); //prints 24.70
So when I have 24.695999999999998 I want to format it as 24.69
You need to take the floor of the double value first - then format it.
Math.floor(double)
Returns the largest (closest to positive infinity) double value that is less than or equal to the argument and is equal to a mathematical integer.
So use something like:
double v = Math.floor(res * 100) / 100.0;
Other alternatives include using BigDecimal.
public void test() {
double d = 0.29;
System.out.println("d=" + d);
System.out.println("floor(d*100)/100=" + Math.floor(d * 100) / 100);
System.out.println("BigDecimal d=" + BigDecimal.valueOf(d).movePointRight(2).round(MathContext.UNLIMITED).movePointLeft(2));
}
prints
d=0.29
floor(d*100)/100=0.28
BigDecimal d=0.29
Multiply the number by 100 and cast it to an integer. This cuts off all the decimal spaces except the two you want. Divide the result by 100.00. (24.69).
int temp = (int)(res * 100);
double result = temp / 100.00;
or the same thing in one line of code:
double result = ((int)(res * 100)) / 100.00;
In addition to using Math.floor(double) and calculating a scale (e.g. * 100 and then / 100.0 for two decimal points) you could use BigDecimal, then you can invoke setScale(int, int) like
double res = 24.695999999999998;
BigDecimal bd = BigDecimal.valueOf(res);
bd = bd.setScale(2, RoundingMode.DOWN);
System.out.println("Value: " + bd);
Which will also give you (the requested)
Value: 24.69
I need to convert a float to an int, as if the comma was removed.
Example:
23.2343f -> 232343
private static int removeComma(float value)
{
for (int i = 0; ; i++) {
if((value * (float)Math.pow(10, i)) % 1.0f == 0.0f)
return (int)(value * Math.pow(10, i));
}
}
The problem is with rounding up of the number. For example if I pass 23000.2359f it becomes 23000236, because it rounded up the input to 23000.236.
Java float doesn't have that much precision, which you can see with
float f = 23000.2359f;
System.out.println(f);
which outputs
23000.236
To get the output you want, you could use a double like
double d = 23000.2359;
String v = String.valueOf(d).replace(".", "");
int val = Integer.parseInt(v);
System.out.println(val);
Output is (the requested)
230002359
you must find a way to get the number of digit after decimal place 1st. Suppose it is n. then multiply the number with 10 times n
double d= 234.12413;
String text = Double.toString(Math.abs(d));
int integerPlaces = text.indexOf('.');
int decimalPlaces = text.length() - integerPlaces - 1;
Please help to convert the string value ("0.25000%") to double value.
0.25000% = 0.0025 (need to get this value as double)
String num = "0.25000%";
double d = Double.parseDouble(num);//does not work
You can try this
String num = "0.25000%";
double d = Double.parseDouble(num.replace("%","")); // remove %
System.out.println(d);
Out put:
0.25
For your edit:
You can divide final answer by 100
System.out.println(d/100);
Now out put:
0.0025
String num = "0.25000%";
BigDecimal d = new BigDecimal(num .trim().replace("%","")).divide(BigDecimal.valueOf(100));//no problem BigDecimal
this can convert for decimal.
Remove the % character and divide by 100
String num = "0.25000%";
double d = Double.parseDouble(num.replace("%","")) / 100;
For example I have the variable 3.545555555, which I would want to truncate to just 3.54.
If you want that for display purposes, use java.text.DecimalFormat:
new DecimalFormat("#.##").format(dblVar);
If you need it for calculations, use java.lang.Math:
Math.floor(value * 100) / 100;
DecimalFormat df = new DecimalFormat(fmt);
df.setRoundingMode(RoundingMode.DOWN);
s = df.format(d);
Check available RoundingMode and DecimalFormat.
None of the other answers worked for both positive and negative values ( I mean for the calculation and just to do "truncate" without Rounding). and without converting to string.
From the How to round a number to n decimal places in Java link
private static BigDecimal truncateDecimal(double x,int numberofDecimals)
{
if ( x > 0) {
return new BigDecimal(String.valueOf(x)).setScale(numberofDecimals, BigDecimal.ROUND_FLOOR);
} else {
return new BigDecimal(String.valueOf(x)).setScale(numberofDecimals, BigDecimal.ROUND_CEILING);
}
}
This method worked fine for me .
System.out.println(truncateDecimal(0, 2));
System.out.println(truncateDecimal(9.62, 2));
System.out.println(truncateDecimal(9.621, 2));
System.out.println(truncateDecimal(9.629, 2));
System.out.println(truncateDecimal(9.625, 2));
System.out.println(truncateDecimal(9.999, 2));
System.out.println(truncateDecimal(-9.999, 2));
System.out.println(truncateDecimal(-9.0, 2));
Results :
0.00
9.62
9.62
9.62
9.62
9.99
-9.99
-9.00
Note first that a double is a binary fraction and does not really have decimal places.
If you need decimal places, use a BigDecimal, which has a setScale() method for truncation, or use DecimalFormat to get a String.
Formating as a string and converting back to double i think will give you the result you want.
The double value will not be round(), floor() or ceil().
A quick fix for it could be:
String sValue = (String) String.format("%.2f", oldValue);
Double newValue = Double.parseDouble(sValue);
You can use the sValue for display purposes or the newValue for calculation.
If, for whatever reason, you don't want to use a BigDecimal you can cast your double to an int to truncate it.
If you want to truncate to the Ones place:
simply cast to int
To the Tenths place:
multiply by ten
cast to int
cast back to double
and divide by ten.
Hundreths place
multiply and divide by 100 etc.
Example:
static double truncateTo( double unroundedNumber, int decimalPlaces ){
int truncatedNumberInt = (int)( unroundedNumber * Math.pow( 10, decimalPlaces ) );
double truncatedNumber = (double)( truncatedNumberInt / Math.pow( 10, decimalPlaces ) );
return truncatedNumber;
}
In this example, decimalPlaces would be the number of places PAST the ones place you wish to go, so 1 would round to the tenths place, 2 to the hundredths, and so on (0 rounds to the ones place, and negative one to the tens, etc.)
You can use NumberFormat Class object to accomplish the task.
// Creating number format object to set 2 places after decimal point
NumberFormat nf = NumberFormat.getInstance();
nf.setMaximumFractionDigits(2);
nf.setGroupingUsed(false);
System.out.println(nf.format(precision));// Assuming precision is a double type variable
3.545555555 to get 3.54.
Try Following for this:
DecimalFormat df = new DecimalFormat("#.##");
df.setRoundingMode(RoundingMode.FLOOR);
double result = new Double(df.format(3.545555555);
This will give= 3.54!
Maybe Math.floor(value * 100) / 100? Beware that the values like 3.54 may be not exactly represented with a double.
Here is the method I use:
double a=3.545555555; // just assigning your decimal to a variable
a=a*100; // this sets a to 354.555555
a=Math.floor(a); // this sets a to 354
a=a/100; // this sets a to 3.54 and thus removing all your 5's
This can also be done:
a=Math.floor(a*100) / 100;
I used Math.floor() method and basic moving of decimal places by (100 = 2).
//3.545555555 to 3.54 by floor method
double x = 3.545555555;
double y = Math.floor(x * 100); //354
double z = y / 100; //3.54
Maybe following :
double roundTwoDecimals(double d) {
DecimalFormat twoDForm = new DecimalFormat("#.##");
return Double.valueOf(twoDForm.format(d));
}
I have a slightly modified version of Mani's.
private static BigDecimal truncateDecimal(final double x, final int numberofDecimals) {
return new BigDecimal(String.valueOf(x)).setScale(numberofDecimals, BigDecimal.ROUND_DOWN);
}
public static void main(String[] args) {
System.out.println(truncateDecimal(0, 2));
System.out.println(truncateDecimal(9.62, 2));
System.out.println(truncateDecimal(9.621, 2));
System.out.println(truncateDecimal(9.629, 2));
System.out.println(truncateDecimal(9.625, 2));
System.out.println(truncateDecimal(9.999, 2));
System.out.println(truncateDecimal(3.545555555, 2));
System.out.println(truncateDecimal(9.0, 2));
System.out.println(truncateDecimal(-9.62, 2));
System.out.println(truncateDecimal(-9.621, 2));
System.out.println(truncateDecimal(-9.629, 2));
System.out.println(truncateDecimal(-9.625, 2));
System.out.println(truncateDecimal(-9.999, 2));
System.out.println(truncateDecimal(-9.0, 2));
System.out.println(truncateDecimal(-3.545555555, 2));
}
Output:
0.00
9.62
9.62
9.62
9.62
9.99
9.00
3.54
-9.62
-9.62
-9.62
-9.62
-9.99
-9.00
-3.54
A quick check is to use the Math.floor method. I created a method to check a double for two or less decimal places below:
public boolean checkTwoDecimalPlaces(double valueToCheck) {
// Get two decimal value of input valueToCheck
double twoDecimalValue = Math.floor(valueToCheck * 100) / 100;
// Return true if the twoDecimalValue is the same as valueToCheck else return false
return twoDecimalValue == valueToCheck;
}
double value = 3.4555;
String value1 = String.format("% .3f", value) ;
String value2 = value1.substring(0, value1.length() - 1);
System.out.println(value2);
double doublevalue= Double.valueOf(value2);
System.out.println(doublevalue);
double firstValue = -3.1756d;
double value1 = (((int)(Math.pow(10,3)*firstValue))/Math.pow(10,3));
In this solution, this will TRUNCATE a double to only two decimal places. This solution will not ROUND OFF the double value.
double myDoubleNumber = 3.545555555;
DecimalFormat df = new DecimalFormat("#.##");
df.setRoundingMode(RoundingMode.DOWN);
double myDoubleNumberTruncated = Double.parseDouble(df.format(myDoubleNumber));
System.out.println(myDoubleNumberTruncated);
This will output 3.54
DecimalFormat("#.##") - Here, I entered two hash symbols(##) after the decimal point. Hence, this will truncate the number up to two decimal places.
This will work for both Positive & Negative values.
This worked for me:
double input = 104.8695412 //For example
long roundedInt = Math.round(input * 100);
double result = (double) roundedInt/100;
//result == 104.87
I personally like this version because it actually performs the rounding numerically, rather than by converting it to a String (or similar) and then formatting it.