What is the equivalent of bcdiv(string, string [, int]) in java
the function divides two arbitrary precision numbers
I would like for instance to use:
bcdiv(10000,100, 2) results in 100.00
or
bcdiv(10000,100, 3) result in 100.000
I am more interested in the precision it gives.
I would like its equivalent in java
link to the php manual
The BigDecimal class allows arbritary precision math. In particular see the divide method.
BigDecimal a = new BigDecimal(10000);//Can take int
BigDecimal b = new BigDecimal("100");//Or string
BigDecimal answer = a.divide(b);
The number has defined structure, but you can format String produced from this number:
String.format("%.2f",10000/100f);
Related
Using Java (JDK 1.8.0_66 and JDK 1.8.0_181) and its built-in BigDecimal class while performing the following operations:
BigDecimal res = new BigDecimal("290");
BigDecimal sub = new BigDecimal("22");
sub = sub.subtract(new BigDecimal("7"));
sub = sub.subtract(new BigDecimal("4"));
res = res.divide(new BigDecimal("22"), 2, RoundingMode.HALF_EVEN);
res = res.multiply(sub);
res = res.setScale(2, RoundingMode.HALF_EVEN);
yields the result of 144.98 while expected is 145.
Why does that happen? I have tried local and an online compiler.
Is setting the scale happening too late? And how can I get a more accurate calculation?
This formula is used to represent monetary value calculations.
The correct answer is 144.98. You compute 290/22 to a presicion of two decimals. The result is 13.18. And 13.18*11 is 144.98
If your computation is "if I were to pay $145 in 11 equal installments, how big should the installments be" you would have to take the difference of 2 cents and add them to the installments.
How can I configure a BigDecimal value so that if it has less that 32 characters, it should be displayed as a plain String, and otherwise it should be represented in an engeneering format?
For instance:
3690215840369.69874120035964120 - plain string
369043523215840369.69874120035964120 - engineering format of representation
I've tried to resolve this in the following way:
BigDecimal bd = new BigDecimal("8678679532108467840356746356832624562456786656736.6456442652456345673656");
System.out.println(bd.toEngineeringString());
System.out.println(bd.toPlainString());
But the outputs are the same. So, how can I gain engineering representation of a BigDecimal instance?
Couldn't you do something like this:
BigDecimal bd = new BigDecimal("8678679532108467840356746356832624562456786656736.6456442652456345673656");
System.out.println(bd.toPlainString().length()<32 ? bd.toPlainString() : bd.toEngineeringString());
and if you need to ignore the decimal point when checking for 32:
BigDecimal bd = new BigDecimal("8678679532108467840356746356832624562456786656736.6456442652456345673656");
int decimalOffset = 0;
if (bd.toPlainString().indexOf('.')>=0)
decimalOffset=1;
System.out.println(bd.toPlainString().length()-decimalOffset<32 ? bd.toPlainString() : bd.toEngineeringString());
but if you're meaning scientific notation, then go check out Steve's answer here and combine that with the first part of my answer by replacing bd.toEngineeringString() with format(bd)
I am reading a currency from XML into Java.
String currency = "135.69";
When I convert this to BigDecimal I get:
System.out.println(new BigDecimal(135.69));
Output:
135.68999999999999772626324556767940521240234375.
Why is it that it outputs this many numbers? How can I avoid this? All I want is for it to output 135.69.
The BigDecimal(double) constructor can have unpredictable behaviors. It is preferable to use BigDecimal(String) or BigDecimal.valueOf(double).
System.out.println(new BigDecimal(135.69)); //135.68999999999999772626324556767940521240234375
System.out.println(new BigDecimal("135.69")); // 135.69
System.out.println(BigDecimal.valueOf(135.69)); // 135.69
The documentation for BigDecimal(double) explains in detail:
The results of this constructor can be somewhat unpredictable. One might assume that writing new BigDecimal(0.1) in Java creates a
BigDecimal which is exactly equal to 0.1 (an unscaled value of 1, with
a scale of 1), but it is actually equal to
0.1000000000000000055511151231257827021181583404541015625. This is because 0.1 cannot be represented exactly as a double (or, for that
matter, as a binary fraction of any finite length). Thus, the value
that is being passed in to the constructor is not exactly equal to
0.1, appearances notwithstanding.
The String constructor, on the other hand, is perfectly predictable: writing new BigDecimal("0.1") creates a BigDecimal which
is exactly equal to 0.1, as one would expect. Therefore, it is
generally recommended that the String constructor be used in
preference to this one.
When a double must be used as a source for a BigDecimal, note that this constructor provides an exact conversion; it does not give
the same result as converting the double to a String using the
Double.toString(double) method and then using the BigDecimal(String)
constructor. To get that result, use the static valueOf(double)
method.
String currency = "135.69";
System.out.println(new BigDecimal(currency));
//will print 135.69
You are storing 135.69 as String in currency. But instead of passing variable currency, you are again passing 135.69(double value) into new BigDecimal().
So you are seeing a lot of numbers in the output.
If you pass the currency variable, your output will be 135.69
May I add something. If you are using currency you should use Scale(2), and you should probably figure out a round method.
BigDecimal b = BigDecimal.valueOf(d);
import java.math.*;
public class Test {
public static void main(String[] args)
{
// Creating a Double Object
Double d = new Double("785.254");
/// Assigning the bigdecimal value of ln to b
BigDecimal b = BigDecimal.valueOf(d);
// Displaying BigDecimal value
System.out.println("The Converted BigDecimal value is: " + b);
}
}
Spring Framework provides an excellent utils class for achieving this.
Util class : NumberUtils
String to BigDecimal conversion -
NumberUtils.parseNumber("135.00", BigDecimal.class);
Hi Guys you cant convert directly string to bigdecimal
you need to first convert it into long after that u will convert big decimal
String currency = "135.69";
Long rate1=Long.valueOf((currency ));
System.out.println(BigDecimal.valueOf(rate1));
I got the following BigDecimal from a Money-Object: BigDecimal 49.99 and I need this as Integer 4999, so everything I ask for is getting rid of the separator.
I could get this BigDecimal as String and remove the separator and parse it to an Integer, but I do not think that this is pretty.
BigDecimal bigPrice = moneyPrice.getValue();
Integer price = bigPrice.intValue();
Using this only responses with 49.
You need the method:
movePointRight(int n)
javadoc link: http://docs.oracle.com/javase/6/docs/api/java/math/BigDecimal.html#movePointRight(int)
example:
BigDecimal bd = new BigDecimal("398.0275");
System.out.println(bd.movePointRight(bd.scale()));
outputs:
3980275
If you want to use the number, just bd=bd.movePointRight(bd.scale());
Try this code:
BigDecimal db = new BigDecimal("49.99");
// multiply with 10^scale ( in your case 2)
db = db.multiply(new BigDecimal(10).pow( db.scale()));
System.out.println(db.intValue());
If it's currency and always to 2 dp, you could multiple it by 100. However as Davio comments, your code should make it clear why you're doing it.
If you want to convert, for example a price in GB pounds sterling to GB pence (100 pence in a pound) then multiplying it by 100 is the right thing to do.
It's not necessary to do any math on the BigDecimal; you can just call myBigDecimal.unscaledValue() to get the underlying unscaled BigInteger directly.
In Java, I want to take a double value and convert it to a BigDecimal and print out its String value to a certain precision.
import java.math.BigDecimal;
public class Main {
public static void main(String[] args) {
double d=-.00012;
System.out.println(d+""); //This prints -1.2E-4
double c=47.48000;
BigDecimal b = new BigDecimal(c);
System.out.println(b.toString());
//This prints 47.47999999999999687361196265555918216705322265625
}
}
It prints this huge thing:
47.47999999999999687361196265555918216705322265625
and not
47.48
The reason I'm doing the BigDecimal conversion is sometimes the double value will contain a lot of decimal places (i.e. -.000012) and the when converting the double to a String will produce scientific notation -1.2E-4. I want to store the String value in non-scientific notation.
I want to have BigDecimal always have two units of precision like this: "47.48". Can BigDecimal restrict precision on conversion to string?
The reason of such behaviour is that the string that is printed is the exact value - probably not what you expected, but that's the real value stored in memory - it's just a limitation of floating point representation.
According to javadoc, BigDecimal(double val) constructor behaviour can be unexpected if you don't take into consideration this limitation:
The results of this constructor can be somewhat unpredictable. One
might assume that writing new BigDecimal(0.1) in Java creates a
BigDecimal which is exactly equal to 0.1 (an unscaled value of 1, with
a scale of 1), but it is actually equal to
0.1000000000000000055511151231257827021181583404541015625. This is because 0.1 cannot be represented exactly as a double (or, for that
matter, as a binary fraction of any finite length). Thus, the value
that is being passed in to the constructor is not exactly equal to
0.1, appearances notwithstanding.
So in your case, instead of using
double val = 77.48;
new BigDecimal(val);
use
BigDecimal.valueOf(val);
Value that is returned by BigDecimal.valueOf is equal to that resulting from invocation of Double.toString(double).
It prints 47.48000 if you use another MathContext:
BigDecimal b = new BigDecimal(d, MathContext.DECIMAL64);
Just pick the context you need.
You want to try String.format("%f", d), which will print your double in decimal notation. Don't use BigDecimal at all.
Regarding the precision issue: You are first storing 47.48 in the double c, then making a new BigDecimal from that double. The loss of precision is in assigning to c. You could do
BigDecimal b = new BigDecimal("47.48")
to avoid losing any precision.
Why not :
b = b.setScale(2, RoundingMode.HALF_UP);
It's printing out the actual, exact value of the double.
Double.toString(), which converts doubles to Strings, does not print the exact decimal value of the input -- if x is your double value, it prints out exactly enough digits that x is the closest double to the value it printed.
The point is that there is no such double as 47.48 exactly. Doubles store values as binary fractions, not as decimals, so it can't store exact decimal values. (That's what BigDecimal is for!)
The String.format syntax helps us convert doubles and BigDecimals to strings of whatever precision.
This java code:
double dennis = 0.00000008880000d;
System.out.println(dennis);
System.out.println(String.format("%.7f", dennis));
System.out.println(String.format("%.9f", new BigDecimal(dennis)));
System.out.println(String.format("%.19f", new BigDecimal(dennis)));
Prints:
8.88E-8
0.0000001
0.000000089
0.0000000888000000000
BigDecimal b = new BigDecimal(c).setScale(2,BigDecimal.ROUND_HALF_UP);
In Java 9 the following is deprecated:
BigDecimal.valueOf(d).setScale(2, BigDecimal.ROUND_HALF_UP);
instead use:
BigDecimal.valueOf(d).setScale(2, RoundingMode.HALF_UP);
Example:
double d = 47.48111;
System.out.println(BigDecimal.valueOf(d)); //Prints: 47.48111
BigDecimal bigDecimal = BigDecimal.valueOf(d).setScale(2, RoundingMode.HALF_UP);
System.out.println(bigDecimal); //Prints: 47.48