Removing a decimal point in java - java

I am wanting to store an integer named Amount, I want it to be stored in pence so if the user entered 11.45 it would be stored as 1145. What is the best way to remove the decimal point? Should I be using decimalFormatting in Java?
Edit:
It is entered in string format, was going to covert it to an int. I will give one of your solutions ago and let you know if it works but not sure which one would be the best.. Thanks everyone.

times it by 100 and cast as int. Use decimal formatting is double / float are too inaccurate which they may be for money

If the user input is in the form of a string (and the format has been verified), then you can strip out the decimal point and interpret the result as an integer (or leave it as a string without the decimal point).
String input = "11.45";
String stripped = input.replace(".", ""); // becomes "1145"
int value = Integer.parseInt(stripped);
If it's a float already, then just multiply by 100 and cast, as #user1281385 suggests.

What about convert to float, multiply by 100 and then convert to int?
String pound = "10.45"; // user-entered string
int pence = (int)Math.round(Float.parseFloat(pound) * 100);
This might be also useful: Best way to parseDouble with comma as decimal separator?

Tested and works. Even if the user enters a number without a decimal, it will keep it as such.
double x = 11.45; // number inputted
String s = String.valueOf(x); // String value of the number inputted
int index = s.indexOf("."); // find where the decimal is located
int amount = (int)x; // intialize it to be the number inputted, in case its an int
if (amount != x) // if the number inputted isn't an int (contains decimal)
// multiply it by 10 ^ (the number of digits after the decimal place)
amount = (int)(x * Math.pow(10,(s.length() - 1 - index)));
System.out.print(amount); // output is 1145
// if x was 11.4500, the output is 1145 as well
// if x was 114500, the output is 114500

Related

How to always keep 2 decimal places in Java

I want to round off any double to a String with 2 decimal places in Java.
I have tried using DecimalFormat but it doesn't give the expected results.
Any help would be appreciated.
Ex: I/P: 3402100.5323
I want to convert this to:
O/P: 34.02
I've tried using DecimalFormat("##,##,##0.00", new DecimalFormatSymbols(Locale.US))
but this results in 34,02,100.53 whereas I want it to output 34.02
PS: If the I/P is 34.02 I would expect it to remain same even after applying the formatting
In my opinion, this can be achieved in 2 steps:
Transform the number into your customised
round-off. (3402100.5323 to 34.021005323). Divide the input with power of 10 to make it round to 2 digits.
Then transformed number can be pretty-printed to truncate value after 2 decimals (34.021005323 to 34.02)
public static void main(String[] args) {
double input = 3402100.5323;
double output = input / getDivisor(input);
System.out.printf("%.2f%n", output);
}
private static double getDivisor(double input) {
int length = String.valueOf((long) input).length();
return Math.pow(10, length - 2) ;
}
Output: 34.02
String.format("%0.2f", 34.021005323)
See
https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#format(java.lang.String,%20java.lang.Object...) and
https://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax
Turning one number into something completely different is, naturally, not the job of decimalformat.
To get from a number representing 3402100.5323 to the string "34.02", first you'd have to get a number that is closer to "34.02". In other words, divide by 10000.0 first.
From there, String.format("%.2f") seems like an easy path: That renders any double to a string, but never using more than 2 digits after the decimal separator. If you want 3400000.123 to turn into "34.00" and not "34", you can make that String.format("%.02f") to force the zeroes.
public String renderWhateverThatIs(double in) {
return String.format("%.02f", in / 100000.0);
}
renderWhateverThatIs(3402100.5323);
> 34,02
Note that the machine locale will dictate if you see a dot or a comma as separator. You can force the issue by explicitly passing a locale to format.
I think what you're looking for is the java.math.BigDecimal class (https://docs.oracle.com/javase/8/docs/api/java/math/BigDecimal.html).
In your case, it would look like this:
BigDecimal rounded = BigDecimal.valueOf(yourDoubleValueHere).setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println(rounded); // 34.02
It can replace doubles (with more complex syntax though) by basically storing numbers in their decimal form, which means you could make operations on it and keep having two decimal places and avoid rounding issues.
EDIT: after thinking about it, it's probably overkill since you only want to get a String with the rounded value, but I'll leave it there just in case.
I don’t believe you can achieve what you want (First 4 digits converted into a 2 digit double with 2 decimal places) in a single step. I’ll break down the steps for an approach that I would try:
Convert the input double to a string
double d = 3402100.5323;
String dStr1 = String.valueOf(d); // dStr1 will be “3402100.5323”
Next, remove the decimal from the string
String dStr2 = dStr1.replace(‘.’,’’); // dStr2 will be “34021005323”
Then, grab the first 4 digits you are interested in
String dStr3 = dStr2.substring(0,4); // dStr3 will be “3402”
Finally, insert a decimal point
String result = dStr3.substring(0,2) + “.” + dStr3.substring(2); // result will be “34.02”
You can use format for this try this out it work 100% for me.
String.format("%.2f", value)
Helpful link
https://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax

How to tell if a result is decimal?

I'm having two float numbers, they can be decimals or not, depending on the operation I want to print the result either with decimal or without.
I'm using String.format to take off the decimal when not needed. However, I have trouble identifying when the result will be decimal. Tried the n1 % n2 > 0 method from a similar question, but when entering for example 6 + 7 the result becomes 13.0 instead of just 13.
Code so far:
float n1 = Float.parseFloat(request.getParameter("num1").toString().trim());
float n2 = Float.parseFloat(request.getParameter("num2").toString().trim());
String res = String.valueOf(n1+n2);
if(n1 % n2 > 0)
{
out.println("It's decimal");
out.println(n1+n2);
}else{
out.println(String.format("%.0f", n1+n2));
}
For doing exact math with non-integers (numbers with fractions) in Java you should use BigDecimal. This class allows for exact representation of non-integers of arbitrary precision.
That is your code should be changed to:
final BigDecimal n1 = new BigDecimal(request.getParameter("num1").toString().trim());
final BigDecimal n2 = new BigDecimal(request.getParameter("num2").toString().trim());
final BigDecimal res = n1.add(n2);
final BigDecimal remainder = n1.remainder(n2);
//if (res.stripTrailingZeros().scale() > 0) {
if (remainder.compareTo(BigDecimal.ZERO) != 0) {
System.out.println("It's decimal");
System.out.println(res);
} else {
final DecimalFormat df = new DecimalFormat("#.0f");
System.out.println(df.format(res));
}
The other answer will not give you the correct result, if a user inputs a number larger than Integer.MAX_VALUE or lower than Integer.MIN_VALUE. Casting to long will probably yield wrong results due to the precision of float that might cause the result to have a decimal fraction even if the input numbers did not...
However I hope you're doing some input validation of the request data. Otherwise you'll most likely get a lot of NumberFormatExceptions from your JSP-page.
UPDATE:
Updated the code example to check for scale instead of precision.
You can use Math.round to tell if a float is an integer. (There are other approaches if your only purpose is to suppress the decimal point for integers when formatting as a string--see KevinO's comment.)
If f is a float, Math.round(f) returns an int, which is f rounded to the nearest integer, unless f is outside the range of an int. However, if f is outside the range of an int, then f must be an integer, for all practical purposes--if f is large enough that it is too big to fit in an int, then it's too big to distinguish between values that are less than 1.0 apart (there are fewer bits of precision in a float than in an int). So there's no way for f to represent a non-integer of that magnitude.
Given that, and assuming that f isn't +/- infinity, you can test whether f is an integer like this:
public boolean isInteger(float f) {
return f > (float)Integer.MAX_VALUE ||
f < (float)Integer.MIN_VALUE ||
f == (float)Math.round(f);
}
But please note that even a non-integer could appear as something.000000 when you format it, since the formatter will have to round f to a certain number of decimal places when printing. It depends on what kind of format you're using.
NOTE: The above method is a correct way to determine whether a float is an integer, if the float is the only information you have. However, in the context of a larger program, there are other considerations. If the parameter string is "2000000000.1", when you parse it as a float you will get 2000000000, which is an integer, because the float doesn't have enough precision to represent the .1. At that point, your float will be an integer value, and it's too late for it to know about the .1--that information has been lost. If you don't want to lose that information, then don't use float or double--use BigDecimal instead.
Cast to int then back:
boolean isDecimal = myFloat != (float)(int)myFloat;
Casting to int truncates the decimal part.
Or, you can use a string approach. Decimals have non-zero digits after the dot, so:
boolean isDecimal = String.valueOf(myFloat).matches(".*\\.(?=.*[1-9]).*");
If you just need that for output, the easiest approach is probably to do this with string manipulation:
String s = String.format("%.4f", n1 + n2); // use whatever decimal places you like
s = s.replaceFirst("\\.0*$", "");
System.out.println(s);
This will fail if the decimal separator in your Locale is , instead of ., so be careful.
To really check if a double value x is integral you can use this test:
if (x % 1 == 0) {
// integral
} else {
// not integral
}

Finding number of digits before a decimal point in java

I have declared the variable for the double I'm using:
z= 345.876;
Now I want to display the number of digits that come before the decimal point. I tried to do the following:
String string_form = new Double(z).toString().subString(0,string_form.indexOf('.'));
double t = Double.valueOf(string_form);
I get an error saying: 'The method subString(int, int) is undefined for the type String'
Then a quick fix shows to change it small case s as: substring. However the error then changes to the string, 'string_form' which says it's not initialized. Any ideas on what to do?
And also how would I modify that to find the number of digits that come after a number? I know in the part
.indexOf('.')
I'd replace the decimal point with a number but how would i change it so that it displays how many digits come AFTER the number, not before? thanks. and yes I have imported the decimalformat text lang.
You're trying to use string_form before you have actually created it.
If you break
String string_form = new Double(z).toString().substring(0,string_form.indexOf('.'));
double t = Double.valueOf(string_form);
into
String string_temp = new Double(z).toString();
String string_form = string_temp.substring(0,string_temp.indexOf('.'));
double t = Double.valueOf(string_form);
Then it should work.
To get the numbers after the decimal point just take the digits from period until the end of the number.
String string_temp = new Double(z).toString();
String string_form = string_temp.substring(string_temp.indexOf('.'), string_temp.length());
double t = Double.valueOf(string_form);
As others have pointed out though, there are many better ways than converting to string and checking for period and reconverting.
The number of decimal digits before the decimal point is given by
(int)Math.log10(z)+1
The number of decimal digits after it is imprecise and depends on how much precision you use when converting to decimal. Floating-point values don't have decimal places, they have binary places, and the two are incommensurable.
just convert the double to a string. find the index of . with indexOf. get the length of the string. subtract the index of . from the length and you should have the count.
String string_form = Double(z).toString();
int index = string_form.indexOf('.');
double d = Double.parse(string_form.substring(0, index+1));
If the numbers are small, you could try
int i = (int) z;
or
long l = Math.round(z);
You're using string_form in the expression string_form.indexOf('.'), but it's not initialized yet, because it's only set after the call to substring(). You need to store the value of toString() in a temporary variable so you can access it in the call to substring(). Something like this
String stringForm = new Double(z).toString();
stringForm = stringForm.substring(stringForm.indexOf('.'));
There are other and better ways to do this, however. Math.floor(z) or even just a cast (long)z will work.
Could do this, for examble:
Integer.parseInt(String.valueOf(possibleBirths).split(".")[0]);
You can do the next thing:
Double z = 345.876;
int a = t.intValue();
int counter = 0;
while(a != 0) {
counter++;
a = a / 10; }
System.out.println(counter);

String trim coming out with incorrect length

I am using Java to determine the length of a double as part of a larger program. At this time the double is 666 but the length is returning as 5, which is a big problem. I read another question posted here with a solution but that didn't work for me. I will show my code and my attempt at emulating the previous solution with results.
My original code:
double Real = 666;
int lengthTest = String.valueOf(Real).trim().length();
System.out.println("Test: " + lengthTest);
This prints 5
Modifications that didn't work, and were essentially just breaking up the code into multiple lines.
double Real = 666;
String part = Real + "";
part = part.trim();
int newLength = part.length();
System.out.println("new length : " + newLength);
This prints 5 as well.
Obviously, I want this to print how many digits I have, in this case it should show 3.
For a bigger picture if it helps I am breaking down number input into constituent parts, and making sure none of them exceed limits. ie: xx.yyezz where xx can be 5 digits, yy can be 5 digits and zz can be 2 digits. Thank you.
That's because you are using a double.
String.valueOf(Real); // returns 666.0, i.e. length 5
Try casting it to an integer first:
Integer simple = (int) Real;
String.valueOf(simple); // returns 666, i.e. length 3.
A double always puts a decimal place after the number. So the number looks like 666.0. You could see this by printing String.valueOf(Real). You should use an int instead or cast the double to an int:
double Real = 666;
int realInt = (int) Real;
System.out.println(String.valueOf(realInt).length());

Print the number of digits before a decimal point

I know there are ways to get the number of digits after a decimal point, for instance the substring method, but how would I go about doing this for the number of digits before a decimal place?
I need to use this to convert US change (double) into Euro change(double). The way I would like to do this is by taking the number before a decimal (such as $1.) and times it by its euro equivalent (.7498) and take the number after a decimal (.16) and times that by its .01 euro coin value (.0075), add both values together to get the euro equivalent of $1.16 (.8698).
To get the number before decimal point,do this:
String str = new Double(your_double_number).toString().subString(0,str.indexOf('.'));
double v = Double.valueOf(str);
If you are using '$' sign then take 1 in place of 0.
Hope it will help you.
convert US change (double) into Euro change(double)
Please don't do that. Never, never, ever use double or float to represent money, because those datatypes cannot represent most decimal fractions, so you get rounding errors before you even start to do any calculations.
Instead, use BigDecimal.
First of all - just multiplying the Dollar value by the exchange rate will get you the euro value so there's no need to do that as far as i can see - you will just introduce rounding errors.
But if you did need to - just use substring
String dollarVal = "$1.16"
String justFullDollar = dollarVal.substring(1, dollarVal.indexOf("."));
String justCents = dollarVal.substring(dollarVal.indexOf(".")+1);
The Correct way would be to store all you money as integers or arbitrary precision objects that way you get no floating point errors too.
Convert to cents, multiply and convert back again.
e.g.
String dollarVal = "$1.16"
BigDecimal dollars = new BigDecimal(dollarVal.substring(1)); //1.16
BigDecimal cents = dollars.multiply(new BigDecimal(100)); //116
BigDecimal eurocents = cents.multiply(new BigDecimal(exchangeRate)); //86.9768
BigDecimal euros = eurocents.divide(new BigDecimal(100)); //0.869768
DecimalFormat formatter = new DecimalFormat("###.00");
String euroVal = "€" + formatter.format(euros);
You can use
String s[] = new Double(your number).toString().split(".");
The s[0] is the number before decimal point. and s[1] is the number after decimal point.
Both are in String, so you need to parse them into double using
double num1 = Double.parseDouble(s[0]);
double num2 = Double.parseDouble(s[1]);

Categories

Resources