How to fetch 3 character in float? - java

I have Float value like 0.152545 I just want 0.1f.
How this is possible..
By using String I was get the String value.The following code show the result.
String pass = pass.substring(0, Math.min(pass.length(), 3));
pass=pass+"f";
This gives me String value like0.1f ,But I want only Float value like 0.1f.

It would be appropriate place where you should use DecimalFormat, And .#f would be pattern for your case.
Find more on Number formatting in java.
Some related question -
Show only two digit after decimal.
Formatting numbers using DecimalFormat

You could use a BigDecimal.
float f = 0.152545f;
BigDecimal bd = new BigDecimal(f);
bd = bd.setScale(1, RoundingMode.DOWN);
f = bd.floatValue();
Works fine even if you have a float stored as a String.
String floatAsString = "0.152545";
BigDecimal bd = new BigDecimal(floatAsString);
bd = bd.setScale(1, RoundingMode.DOWN);
float f = bd.floatValue();

You could do:
DecimalFormat format = new DecimalFormat("0.0");
format.setRoundingMode(RoundingMode.DOWN);
format.setMaximumFractionDigits(1);
System.out.println(format.format(0.152545) + "f");

How about
float new = Math.round( 10.0 * f ) / 10.0;
It won't be precise, as floats/doubles are just sums of finite series of 1/2^n, but might be good enough for you.
Perhaps you should be thinking about presenting the float with one significant decimal point and keep full precision internally?
Cheers,

Related

Best method to round a double in Java 12/13? [duplicate]

This question already has answers here:
How to round a number to n decimal places in Java
(39 answers)
Closed 8 years ago.
If the value is 200.3456, it should be formatted to 200.34.
If it is 200, then it should be 200.00.
Here's an utility that rounds (instead of truncating) a double to specified number of decimal places.
For example:
round(200.3456, 2); // returns 200.35
Original version; watch out with this
public static double round(double value, int places) {
if (places < 0) throw new IllegalArgumentException();
long factor = (long) Math.pow(10, places);
value = value * factor;
long tmp = Math.round(value);
return (double) tmp / factor;
}
This breaks down badly in corner cases with either a very high number of decimal places (e.g. round(1000.0d, 17)) or large integer part (e.g. round(90080070060.1d, 9)). Thanks to Sloin for pointing this out.
I've been using the above to round "not-too-big" doubles to 2 or 3 decimal places happily for years (for example to clean up time in seconds for logging purposes: 27.987654321987 -> 27.99). But I guess it's best to avoid it, since more reliable ways are readily available, with cleaner code too.
So, use this instead
(Adapted from this answer by Louis Wasserman and this one by Sean Owen.)
public static double round(double value, int places) {
if (places < 0) throw new IllegalArgumentException();
BigDecimal bd = BigDecimal.valueOf(value);
bd = bd.setScale(places, RoundingMode.HALF_UP);
return bd.doubleValue();
}
Note that HALF_UP is the rounding mode "commonly taught at school". Peruse the RoundingMode documentation, if you suspect you need something else such as Bankers’ Rounding.
Of course, if you prefer, you can inline the above into a one-liner:
new BigDecimal(value).setScale(places, RoundingMode.HALF_UP).doubleValue()
And in every case
Always remember that floating point representations using float and double are inexact.
For example, consider these expressions:
999199.1231231235 == 999199.1231231236 // true
1.03 - 0.41 // 0.6200000000000001
For exactness, you want to use BigDecimal. And while at it, use the constructor that takes a String, never the one taking double. For instance, try executing this:
System.out.println(new BigDecimal(1.03).subtract(new BigDecimal(0.41)));
System.out.println(new BigDecimal("1.03").subtract(new BigDecimal("0.41")));
Some excellent further reading on the topic:
Item 48: "Avoid float and double if exact answers are required" in Effective Java (2nd ed) by Joshua Bloch
What Every Programmer Should Know About Floating-Point Arithmetic
If you wanted String formatting instead of (or in addition to) strictly rounding numbers, see the other answers.
Specifically, note that round(200, 0) returns 200.0. If you want to output "200.00", you should first round and then format the result for output (which is perfectly explained in Jesper's answer).
If you just want to print a double with two digits after the decimal point, use something like this:
double value = 200.3456;
System.out.printf("Value: %.2f", value);
If you want to have the result in a String instead of being printed to the console, use String.format() with the same arguments:
String result = String.format("%.2f", value);
Or use class DecimalFormat:
DecimalFormat df = new DecimalFormat("####0.00");
System.out.println("Value: " + df.format(value));
I think this is easier:
double time = 200.3456;
DecimalFormat df = new DecimalFormat("#.##");
time = Double.valueOf(df.format(time));
System.out.println(time); // 200.35
Note that this will actually do the rounding for you, not just formatting.
The easiest way, would be to do a trick like this;
double val = ....;
val = val*100;
val = Math.round(val);
val = val /100;
if val starts at 200.3456 then it goes to 20034.56 then it gets rounded to 20035 then we divide it to get 200.34.
if you wanted to always round down we could always truncate by casting to an int:
double val = ....;
val = val*100;
val = (double)((int) val);
val = val /100;
This technique will work for most cases because for very large doubles (positive or negative) it may overflow. but if you know that your values will be in an appropriate range then this should work for you.
Please use Apache commons math:
Precision.round(10.4567, 2)
function Double round2(Double val) {
return new BigDecimal(val.toString()).setScale(2,RoundingMode.HALF_UP).doubleValue();
}
Note the toString()!!!!
This is because BigDecimal converts the exact binary form of the double!!!
These are the various suggested methods and their fail cases.
// Always Good!
new BigDecimal(val.toString()).setScale(2,RoundingMode.HALF_UP).doubleValue()
Double val = 260.775d; //EXPECTED 260.78
260.77 - WRONG - new BigDecimal(val).setScale(2,RoundingMode.HALF_UP).doubleValue()
Double val = 260.775d; //EXPECTED 260.78
260.77 - TRY AGAIN - Math.round(val * 100.d) / 100.0d
Double val = 256.025d; //EXPECTED 256.03d
256.02 - OOPS - new DecimalFormat("0.00").format(val)
// By default use half even, works if you change mode to half_up
Double val = 256.025d; //EXPECTED 256.03d
256.02 - FAIL - (int)(val * 100 + 0.5) / 100.0;
double value= 200.3456;
DecimalFormat df = new DecimalFormat("0.00");
System.out.println(df.format(value));
If you really want the same double, but rounded in the way you want you can use BigDecimal, for example
new BigDecimal(myValue).setScale(2, RoundingMode.HALF_UP).doubleValue();
double d = 28786.079999999998;
String str = String.format("%1.2f", d);
d = Double.valueOf(str);
For two rounding digits. Very simple and you are basically updating the variable instead of just display purposes which DecimalFormat does.
x = Math.floor(x * 100) / 100;
Rounding a double is usually not what one wants. Instead, use String.format() to represent it in the desired format.
In your question, it seems that you want to avoid rounding the numbers as well? I think .format() will round the numbers using half-up, afaik?
so if you want to round, 200.3456 should be 200.35 for a precision of 2. but in your case, if you just want the first 2 and then discard the rest?
You could multiply it by 100 and then cast to an int (or taking the floor of the number), before dividing by 100 again.
200.3456 * 100 = 20034.56;
(int) 20034.56 = 20034;
20034/100.0 = 200.34;
You might have issues with really really big numbers close to the boundary though. In which case converting to a string and substring'ing it would work just as easily.
value = (int)(value * 100 + 0.5) / 100.0;

convert double values in decimal (fraction) values java

I have below code:
Double a = new Double((123456798/1000000)); //123456798 this value comes from client side as a `int`
DecimalFormat df = new DecimalFormat("###.###");
log.info("a :"+a+" df "+df.format(a.doubleValue()));
output:
a :123.0 df 123
//i want output like this, a :123.xxx fd 123.xxx
please help
UPDATE:
123456798 this value comes from client side as a int so i cant do it as 123456798.0 (or something)
123456798 and 1000000 are int literals, so dividing them will use integer arithmetic, and yield 123.
Instead, you could use floating point literals in order to use floating point arithmetic:
Double a = new Double((123456798.0/1000000.0));
DecimalFormat df = new DecimalFormat("###.###");
log.info("a :"+a+" df "+df.format(a.doubleValue()));
Any one value in the division should be float or double.
Double a = new Double((123456798.0/1000000));
or
Double a = new Double((123456798/1000000.0));
if you are getting these values in variables, then multiply it with 1.0
like
Double a = new Double((variable*1.0/1000000));
Put it like that
Double a = new Double((123456798.0/1000000.0)); // <- note ".0"
the reason of the misbehavior is the integer division:
123456798/1000000
is the integer value, while
123456798.0/1000000.0
is the floating point one (double)
Double a = new Double((123456798/1000000));
You are doing integer division here. Make one of the constants a double, so that floating-point division is done. Also, why are you using Double? It's better to use the primitive type double.
double a = 123456798.0 / 1000000;
Or simply, since they are constants:
double a = 123.456789;
You perform an integer division, thats why a is incorrect:
Double a = new Double(123456798.0/1000000);

Using BigDecimal correctly

I'm not sure if I'm doing this right.
I'm doing scientific calculations that need to be accurate as possible so I am converting the existing use of Double to BigDecimal.
// before
double tmp = x - (y / z);
// after
BigDecimal tmp = new BigDecimal(
x.value().subtract(y.value().divide(z.value())).toString());
Is this logical or what?
You are doing your arithmetics with doubles before converting the result to BigDecimal. That way you don't gain any precision.
You should convert every number to BigDecimal as soon as possible and then use the methods of BigDecimals (subtract, divide and so on) on the BigDecimal representation to do the arithmetics.
BigDecimal bdX = new BigDecimal(x);
BigDecimal bdY = new BigDecimal(y);
BigDecimal bdZ = new BigDecimal(z);
BigDecimal tmp = bdX.subtract(bdY.divide(bdZ));
BigDecimal has methods for all the operators. You should use them instead. You can also control (specify) the scale and rounding.
Avoid using doulbles, instead use BigDecimal from the beginning.
Assuming that x, y and z are doubles
BigDecimal tmp = new BigDecimal(x).subtract(
new BigDecimal(y).divide(new BigDecimal(z), MathContext.DECIMAL64));
see BigDecimal.divide API to understand why to use MathContext

Rounding a Double to 2dp

I am currently trying to write a program which rounds a "double" variable to two decimal places.
I have the method:
DecimalFormat df = new DecimalFormat("#.00");
However, when I apply the method:
double x = df.format(y-z);
I get an error telling me a "double" was expected but a "string" was found.
Any suggestions as to how to fix this?
Thanks!
Try this
#Test
public void test() {
int f = 100;
double d = 123.456;
double temp = d * f;
double rounded = Math.round(temp);
double to2dp = rounded / f;
Assert.assertEquals(123.46, to2dp, 0.00001);
}
The f = 100 is fro 2dp. You would use f = 10 for 1dp etc
If you are using doubles to store/calculate currency values, then you will likely find yourself in a world of pain with rounding. Been there, done that, got the scars.
I highly recommend that you use BigDecimal values for ALL currency values, and do not even involve doubles in the instantiation. Always use the String constructor.
See related questions here and here.
In a comment on my other answer, Gary Rowe has suggested the use of Joda Money as a solution.
Now while this may be a fine product, and I have to admit that I have not tried it, I am a bit concerned about the following example in their documentation:
// multiplies by 3.5 with rounding
money = money.multipliedBy(3.5d, RoundingMode.DOWN);
Now this is an interesting example because they have used a double amount which can be represented exactly using double precision.
To illustrate this, let's take the following unit test as an example:
double d1 = 3.5d;
BigDecimal bd1 = new BigDecimal(d1);
System.out.println("BD version of " + d1 + " = " + bd1);
BigDecimal bd2 = new BigDecimal("10000000");
BigDecimal bd3 = bd2.multiply(bd1);
System.out.println("Result in bd3 = " + bd3);
This yields the following output:
BD version of 3.5 = 3.5
Result in bd3 = 35000000.0
However, if you change the '3.5d' to '3.4d', you get a very different result:
BD version of 3.4 = 3.399999999999999911182158029987476766109466552734375
Result in bd3 = 33999999.999999999111821580299874767661094665527343750000000
Now the Joda Money classes may deal with this (somehow), but introducing any double precision numbers into the mix is fraught with danger.
Gary, perhaps you could comment about the result of a similar calculation in Joda Money.

Round a double to 2 decimal places [duplicate]

This question already has answers here:
How to round a number to n decimal places in Java
(39 answers)
Closed 8 years ago.
If the value is 200.3456, it should be formatted to 200.34.
If it is 200, then it should be 200.00.
Here's an utility that rounds (instead of truncating) a double to specified number of decimal places.
For example:
round(200.3456, 2); // returns 200.35
Original version; watch out with this
public static double round(double value, int places) {
if (places < 0) throw new IllegalArgumentException();
long factor = (long) Math.pow(10, places);
value = value * factor;
long tmp = Math.round(value);
return (double) tmp / factor;
}
This breaks down badly in corner cases with either a very high number of decimal places (e.g. round(1000.0d, 17)) or large integer part (e.g. round(90080070060.1d, 9)). Thanks to Sloin for pointing this out.
I've been using the above to round "not-too-big" doubles to 2 or 3 decimal places happily for years (for example to clean up time in seconds for logging purposes: 27.987654321987 -> 27.99). But I guess it's best to avoid it, since more reliable ways are readily available, with cleaner code too.
So, use this instead
(Adapted from this answer by Louis Wasserman and this one by Sean Owen.)
public static double round(double value, int places) {
if (places < 0) throw new IllegalArgumentException();
BigDecimal bd = BigDecimal.valueOf(value);
bd = bd.setScale(places, RoundingMode.HALF_UP);
return bd.doubleValue();
}
Note that HALF_UP is the rounding mode "commonly taught at school". Peruse the RoundingMode documentation, if you suspect you need something else such as Bankers’ Rounding.
Of course, if you prefer, you can inline the above into a one-liner:
new BigDecimal(value).setScale(places, RoundingMode.HALF_UP).doubleValue()
And in every case
Always remember that floating point representations using float and double are inexact.
For example, consider these expressions:
999199.1231231235 == 999199.1231231236 // true
1.03 - 0.41 // 0.6200000000000001
For exactness, you want to use BigDecimal. And while at it, use the constructor that takes a String, never the one taking double. For instance, try executing this:
System.out.println(new BigDecimal(1.03).subtract(new BigDecimal(0.41)));
System.out.println(new BigDecimal("1.03").subtract(new BigDecimal("0.41")));
Some excellent further reading on the topic:
Item 48: "Avoid float and double if exact answers are required" in Effective Java (2nd ed) by Joshua Bloch
What Every Programmer Should Know About Floating-Point Arithmetic
If you wanted String formatting instead of (or in addition to) strictly rounding numbers, see the other answers.
Specifically, note that round(200, 0) returns 200.0. If you want to output "200.00", you should first round and then format the result for output (which is perfectly explained in Jesper's answer).
If you just want to print a double with two digits after the decimal point, use something like this:
double value = 200.3456;
System.out.printf("Value: %.2f", value);
If you want to have the result in a String instead of being printed to the console, use String.format() with the same arguments:
String result = String.format("%.2f", value);
Or use class DecimalFormat:
DecimalFormat df = new DecimalFormat("####0.00");
System.out.println("Value: " + df.format(value));
I think this is easier:
double time = 200.3456;
DecimalFormat df = new DecimalFormat("#.##");
time = Double.valueOf(df.format(time));
System.out.println(time); // 200.35
Note that this will actually do the rounding for you, not just formatting.
The easiest way, would be to do a trick like this;
double val = ....;
val = val*100;
val = Math.round(val);
val = val /100;
if val starts at 200.3456 then it goes to 20034.56 then it gets rounded to 20035 then we divide it to get 200.34.
if you wanted to always round down we could always truncate by casting to an int:
double val = ....;
val = val*100;
val = (double)((int) val);
val = val /100;
This technique will work for most cases because for very large doubles (positive or negative) it may overflow. but if you know that your values will be in an appropriate range then this should work for you.
Please use Apache commons math:
Precision.round(10.4567, 2)
function Double round2(Double val) {
return new BigDecimal(val.toString()).setScale(2,RoundingMode.HALF_UP).doubleValue();
}
Note the toString()!!!!
This is because BigDecimal converts the exact binary form of the double!!!
These are the various suggested methods and their fail cases.
// Always Good!
new BigDecimal(val.toString()).setScale(2,RoundingMode.HALF_UP).doubleValue()
Double val = 260.775d; //EXPECTED 260.78
260.77 - WRONG - new BigDecimal(val).setScale(2,RoundingMode.HALF_UP).doubleValue()
Double val = 260.775d; //EXPECTED 260.78
260.77 - TRY AGAIN - Math.round(val * 100.d) / 100.0d
Double val = 256.025d; //EXPECTED 256.03d
256.02 - OOPS - new DecimalFormat("0.00").format(val)
// By default use half even, works if you change mode to half_up
Double val = 256.025d; //EXPECTED 256.03d
256.02 - FAIL - (int)(val * 100 + 0.5) / 100.0;
double value= 200.3456;
DecimalFormat df = new DecimalFormat("0.00");
System.out.println(df.format(value));
If you really want the same double, but rounded in the way you want you can use BigDecimal, for example
new BigDecimal(myValue).setScale(2, RoundingMode.HALF_UP).doubleValue();
double d = 28786.079999999998;
String str = String.format("%1.2f", d);
d = Double.valueOf(str);
For two rounding digits. Very simple and you are basically updating the variable instead of just display purposes which DecimalFormat does.
x = Math.floor(x * 100) / 100;
Rounding a double is usually not what one wants. Instead, use String.format() to represent it in the desired format.
In your question, it seems that you want to avoid rounding the numbers as well? I think .format() will round the numbers using half-up, afaik?
so if you want to round, 200.3456 should be 200.35 for a precision of 2. but in your case, if you just want the first 2 and then discard the rest?
You could multiply it by 100 and then cast to an int (or taking the floor of the number), before dividing by 100 again.
200.3456 * 100 = 20034.56;
(int) 20034.56 = 20034;
20034/100.0 = 200.34;
You might have issues with really really big numbers close to the boundary though. In which case converting to a string and substring'ing it would work just as easily.
value = (int)(value * 100 + 0.5) / 100.0;

Categories