I want to convert number 2.55 to 255 in java.
I have tried the following code but I am getting 254 instead of 255:
final Double tmp = 2.55;
final Double d = tmp * 100;
final Integer i = d.intValue();
What is the correct way to achieve this?
you have to round that value, and you can use primitives for that..
i.e. use the primitive double instead of the wrapper class Double
final double tmp = 2.55;
final double d = tmp * 100;
long i = Math.round(d);
System.out.println("round: "+ i);
It is simple by using BigDecimal
BigDecimal bg1 = new BigDecimal("123.23");
BigDecimal bg2 = new BigDecimal("12323");
bg1= bg1.movePointLeft(-2); // 3 points right
bg2= bg2.movePointLeft(3); // 3 points left
System.out.println(bg1); //12323
System.out.println(bg2); //12.323
the value of d is 254.999999999997.
this is a problem with floating point calculations.
you could use
i = Math.round(d);
to get 255.
--- delete the bottom.. was wrong
Related
I have two double values
double a = 1.07522;
double b = 1.0752;
and rounding multiplier value
public static final double ROUND_MULTIPLIER = 100000.0;
So there always should be 5 decimal places.
I need to subtract two double values and get result as a - b = 0.00002.
How can I do this with using ROUND_MULTIPLIER ?
I tried using BigDecimal as
BigDecimal.valueOf(a).subtract(BigDecimal.valueOf(b)).round(new MathContext((int)ROUND_MULTIPLIER));
but it not always works, sometimes return 2E-16, it returns weird value when try add to second value as below
BigDecimal.valueOf(a).subtract(BigDecimal.valueOf(b + 0.00002)).round(new MathContext((int)ROUND_MULTIPLIER));
I need to use ROUND_MULTIPLIER.
I don't understand why you must use ROUND_MULTIPLYER and what the exact reason of it's existance is, so I can only guess.
Forcing the code to use ROUND_MULTIPLYER:
public static final double ROUND_MULTIPLIER = 100000.0;
public void foobar()
{
double a = 1.07522;
double b = 1.0752;
BigDecimal opA = BigDecimal.valueOf(a);
BigDecimal opB = BigDecimal.valueOf(b);
BigDecimal result = opA.subtract(opB);
result = result.multiply(BigDecimal.valueOf(ROUND_MULTIPLIER));
int cutResult = result.intValue();
result = BigDecimal.valueOf(cutResult / ROUND_MULTIPLIER);
System.out.println(result);
}
The output of this is
0.000020
Is that what you want? The code is definitly object to optimization, but I let that up to you to do ;-)
Use bigDEcimal and set the scale giving the number of decimals you need
final BigDecimal a = new BigDecimal(1.07522);
final BigDecimal b = new BigDecimal(1.0752);
final BigDecimal result = a.subtract(b);
int newScale = 10; //10 decimals
System.out.println(result.setScale(newScale, BigDecimal.ROUND_UP));
BigDecimal decimal = new BigDecimal(1.07522);
BigDecimal decimal1 = new BigDecimal(1.0752);
System.out.println(decimal.subtract(decimal1).setScale(5, RoundingMode.DOWN));
BigDecimal is the way to go, but why is the ROUND_MULTIPLIER a double value if you cast it to int anyways. Maybe that is where you get your rounding issues from? Give it a spin with an int-multiplier :)
Edit: using setScale() setting a proper rounding mode is usually a better choice, but you insist on using the multiplier, right?
I have a problem when converting a String to Double.
Decimals that remain to the right and are 0 are lost.
I have seen you can solve with the BigDecimal type, but I don't want to use it.
Anyone know any way to fix it?
Regards,
This is an example(using java.Text.DecimalFormat):
Double d = 0.85; // 0.85
DecimalFormat mf = new DecimalFormat("#0.000");
String s = mf.format(d); // "0,850"
s = s.replace(',', '.'); // "0.850"
double conv = Double.parseDouble(s); //0.85
//String -> Double = 0.850???
I am just trying to learn more about BigDecimal, but below code makes me confuse.
Double x = 1.2;
String y = "1.2";
BigDecimal a = BigDecimal.ZERO;
BigDecimal b = BigDecimal.ZERO;
a = new BigDecimal(x);
b = new BigDecimal(y);
int res = res = b.compareTo(a);
if(res==1){
System.out.println("Die");
}else if(res ==0){
System.out.println("Live");
}else if (res==-1){
System.out.println("God Loves you");
}
Result = Die
I am not ready to "Die", why BigDecimal is hell bent on killing me.
This statement:
Double x = 1.2;
assigns the nearest double-representable value to 1.2 to x. That's just less than 1.2 - the value 1.2 itself can't be represented exactly in binary.
Now when you create a BigDecimal from that value, that "not quite 1.2" value is retained exactly. From the constructor's documentation:
Translates a double into a BigDecimal which is the exact decimal representation of the double's binary floating-point value.
... whereas when you use new BigDecimal("1.2") the result is exactly 1.2 - BigDecimal parses the string, and any decimal string representation can be represented exactly by BigDecimal, as that's the whole point of it.
1.2 is slightly bigger than "the nearest double representation of 1.2" hence res is 1.
a = new BigDecimal(x); // a= 1.1999999999999999555910790149937383830547332763671875
b = new BigDecimal(y); // b=1.2
This is due to conversion issue since translates a double into a BigDecimal which is the exact decimal representation.
int res = res = b.compareTo(a); //res= 1
Because 1.2 as double is not what you expect it to be.
Try this:
BigDecimal a = new BigDecimal(String.valueOf(x));
BigDecimal b = new BigDecimal(y);
I need to round some Doubles to 3 to 4 decimals. I tried 3 different methods, none of them work.
For most of the double I have, it works, but I keep having such doubles anyway :
0.12919999999999998
0.12365000000000001
36371.922099999996
I tried the following methods so far :
-- 1
(double) Math.round(someDouble * 10000) / 10000
-- 2
DecimalFormat twoDForm = new DecimalFormat("0.0000");
twoDForm.format(someDouble);
-- 3
BigDecimal bd = new BigDecimal(someDouble);
bd = bd.setScale(4, BigDecimal.ROUND_HALF_UP);
Does anyone have the magic solution I am looking for :) ?
Thank you !
NOTE :
Here is the full code :
// Processing
long start = System.nanoTime();
for (int i = 0; i < loopSize; i++) {
process();
}
// end timer
long absTime = System.nanoTime() - start;
double absTimeMilli = absTime * 1e-6;
DecimalFormat t = new DecimalFormat("###.####");
context.setTotalTime(Double.valueOf(t.format(absTimeMilli)));
context.setUnit(TimeUnit.SECONDS);
context.setMeanTime(Double.valueOf(t.format(absTimeMilli / Const.BENCH_LOOP_COUNT)));
context.setExecPerTimeUnit(Double.valueOf(t.format(loopSize / (absTimeMilli*1e-3))));
If you are storing the result back into a double type (your first example hints that you are), then this will happen. Double cannot store some numbers.
Once you have rounded, store the result in a BigDecimal or a String.
Updated - see comments below
May have misunderstood your comment, but something like this.
// this.totalTime += (1.0/someInteger)*myValue
BigDecimal ratio = BigDecimal.ONE.divide(new BigDecimal(someInteger));
totalTime = totalTime.add(ratio.multiply(myValue));
double val = 2.33333333;
DecimalFormat df2 = new DecimalFormat("###.####");
Try this.
A double cannot represent all possible decimal values due to the limitations in floating point representation (see http://en.wikipedia.org/wiki/Floating_point for more info or just google "floating ponint precision problem"). So if you need to process the rounded values simply store them in a BigDecimal, round it and keep working with that instead of going back to a double.
here is what i know so far ... to round a double you should use BigDecimal like this:
double yourDouble = 0.123456789;
int scale = 3;
double yourRoundedDouble = new BigDecimal(yourDouble).setScale(scale, RoundingMode.HALF_UP).doubleValue();
the result would be : 0.123.
note that "scale" is the number of digits you want to have after the point.
Hope this helps.
I am not sure what are you looking for, I do these sort of calculations like this
double p=36371.922099999996;
p=Math.round(p *10000.0000)/10000.0000;
System.out.println(p);
and I get 36371.9221
Try it
I have a BigDecimal variable
BigDecimal x = new BigDecimal("5521.0000000001");
Formula:
x = x.add(new BigDecimal("-1")
.multiply(x.divideToIntegralValue(new BigDecimal("1.0"))));
I want to remove the integer part, to get the value x = ("0.0000000001"), but my new value is 1E-10 and not the 0.0000000001.
To get a String representation of the BigDecimal without the exponent part, you can use
BigDecimal.toPlainString(). In your example:
BigDecimal x = new BigDecimal("5521.0000000001");
x = x.add(new BigDecimal("-1").
multiply(x.divideToIntegralValue(new BigDecimal("1.0"))));
System.out.println(x.toPlainString());
prints
0.0000000001
Try using BigDecimal.toPlainString() to get value as plain string as you require.
Perhaps using BigDecimal isn't really helping you.
double d = 5521.0000000001;
double f = d - (long) d;
System.out.printf("%.10f%n", f);
prints
0.0000000001
but the value 5521.0000000001 is only an approximate representation.
The actual representation is
double d = 5521.0000000001;
System.out.println(new BigDecimal(d));
BigDecimal db = new BigDecimal(d).subtract(new BigDecimal((long) d));
System.out.println(db);
prints
5521.000000000100044417195022106170654296875
1.00044417195022106170654296875E-10
I suspect whatever you are trying to is not meaningful as you appear to be trying to obtain a value which is not what you think it is.
If you want to do this at your BigDecimal object and not convert it into a String with a formatter you can do it on Java 8 with 2 steps:
stripTrailingZeros()
if scale < 0 setScale to 0 if don't like esponential/scientific
notation
You can try this snippet to better understand the behaviour
BigDecimal bigDecimal = BigDecimal.valueOf(Double.parseDouble("50"));
bigDecimal = bigDecimal.setScale(2);
bigDecimal = bigDecimal.stripTrailingZeros();
if (bigDecimal.scale()<0)
bigDecimal= bigDecimal.setScale(0);
System.out.println(bigDecimal);//50
bigDecimal = BigDecimal.valueOf(Double.parseDouble("50.20"));
bigDecimal = bigDecimal.setScale(2);
bigDecimal = bigDecimal.stripTrailingZeros();
if (bigDecimal.scale()<0)
bigDecimal= bigDecimal.setScale(0);
System.out.println(bigDecimal);//50.2
bigDecimal = BigDecimal.valueOf(Double.parseDouble("50"));
bigDecimal = bigDecimal.setScale(2);
bigDecimal = bigDecimal.stripTrailingZeros();
System.out.println(bigDecimal);//5E+1
bigDecimal = BigDecimal.valueOf(Double.parseDouble("50.20"));
bigDecimal = bigDecimal.setScale(2);
bigDecimal = bigDecimal.stripTrailingZeros();
System.out.println(bigDecimal);//50.2