Double validation - java

I have the below json property which holds the numeric value
"creditLimit": "844500"
which has the following conditions:
Should not exceed 10 digits
Must be a whole number, should not have decimals
Below are example valid inputs for which I want to throw a validation error message back to the user, saying invalid entry:
45500.00
9876543210
Example invalid inputs:
540.50
98765432109
When I tried
Double.valueOf(ent.creditLimit).intValue()
the final value alters, looks like it round off the value.
I do not want to keep the decimals.
How to retain the exact value? Thanks in advance

You could either use a regular expression to validate or you could parse as a BigDecimal then use intValueExact():
BigDecimal bd = new BigDecimal("540.50");
try
{
bd.intValueExact();
//number is a whole number
} catch(ArithmeticException e)
{
//number is not a whole number
}

Ensure there is a javax.validation implementation in your classpath/runtime.
In your JSON-Pojo, then:
#javax.validation.constraints.Pattern(regexp = "^\\d{1,10}$")
private String creditLimit;
Allows only numerical strings of length 1 to 10. Throws exception otherwise.

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

JSONArray(jsonstring) drops decimal if 0

I have a json string with floating values:
{"foo":10.0,"bar":12.005}
I need to convert it using JSONObject(jsonstring) and I need to retain the decimals, but the json array drops them if they are zero. The result looks like
{"foo":10,"bar":12.005}
I expected that i could provide additional parameters to control the data type but according to
https://developer.android.com/reference/org/json/JSONObject
there is no such option. I also searched google and stackoverflow but i cannot find any similar problems.
JSONObject always treats everything as Objects so they must be converted to float by parsing it.
String json = "{\"foo\":10.0}";
try{
JSONObject jo = new JSONObject(json);
float f = Float.parseFloat(jo.get("foo").toString());
System.out.println(f);
}
catch(Exception e){
// Some parsing exception occurs
}
Hope this solves the issue.
Also JSONObject supports methods for getting the items in various datatype like double, int, boolean
double d = jo.getDouble("foo");
System.out.println(d); // gave me 10.0
Similarly we have
int i = getInt("name"); // which returns an integer
boolean b = getBoolean("name"); // Automatically parses
There's no way to get the number of digits from JSON.parse or eval. Even if IBM's decimal proposal had been adopted by the EcmaScript committee, the number is still going to be parsed to an IEEE 754 float.
Take a look a http://code.google.com/p/json-sans-eval/source/browse/trunk/src/json_sans_eval.js for a simple JSON parser that you can modify to keep precision info.
solution already provided here
How to prevent removing decimal point when parsing JSON?
This is the expected behaviour.
The DECIMAL field is converted to the JSON NUMBER data type.
This type trims trailing zeros by default.
It's up to the client/receiver of the JSON to decide how many decimal places it needs to show and set the correct display format.
For the 10.0 it will add value as an integer in JSON, if you want it with decimal then first you need to convert it as a string and then you need to put string value in JSON.
val foo = 10.0
val bar = 12.005
val strFoo = foo.toString();
val jsonObject = JSONObject()
jsonObject.put("foo",strFoo)
jsonObject.put("bar", bar)
I guess, it's not a problem of JSON array, rather language's type conversion from float to int.
Use something similar to this to format float to string String.format("%,.2f", val);
Edit
The Workflow will go as follows:
if(Math.ceil(val)==val){ //a number with no fractional points
String str = String.format("%,.2f", val);
}
else //use_the_floating_number_as_usual

Reading long binary numbers in java

I am trying to write a program which converts binary numbers into decimal, however as soon as I have a binary number which is bigger than 10 digits I get a java.lang.numberformatexception error. I was wondering how I should rewrite my code in order to handle binary numbers:
try{
//will throw an exception if the user's input contains a non-Integer
int inputNumber = Integer.parseInt(returnEnterNumber());
//when our user wants to convert from binary to decimal
if(binaryToDecimal.isSelected()){
//checks if number is binary
int checkNumber = inputNumber;
while (checkNumber != 0) {
if (checkNumber % 10 > 1) {
throw new InvalidBinaryException();
}
checkNumber = checkNumber / 10;
}
//converts from binary and outputs result
int n = Integer.parseInt(returnEnterNumber(), 2);
displayConvertedNumber(Integer.toString(n));
}
}
catch(Exception e) {
displayConvertedNumber("WRONG INPUT! - TRY again");
}
Edit: I understand why the code fails, seeing as how it takes the number as a decimal and overflows. I am not sure how to rewrite the code to take the input as a binary straight away.
That's not a valid way to check a binary number. You're converting to an int in base 10, then checking that each of the digits in base 10 is zero or one. The conversion itself will fail on long enough input strings, and if it doesn't the checking will fail as well.
You shouldn't be converting it all all, you should be checking the input string itself.
EDIT Actually you don't have to do anything. Integer.parseInt() will check it for you and throw NumberFormatException if the string isn't a number in the specified radix.
You are parsing your binary digit string as a decimal integer first. If it has more than 10 significant digits then its decimal interpretation is too big to fit in an int, so the decimal conversion fails.
When you are going to parse the digit string as a binary number, simply avoid first parsing it as a decimal one. For instance, most of what you posted could be reduced to this:
int inputNumber = Integer.parseInt(returnEnterNumber(),
binaryToDecimal.isSelected() ? 2 : 10);
Take a look at Integers MAX values:
public class MainClass {
public static void main(String[] arg) {
System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MIN_VALUE);
}
}
the output will be:
2147483647
-2147483648
This means that if you have more than 10 digits, you have exceeded the max number for the Integer data type.
Try Using BigInteger on your binary value or consider returning it as String
Here is one line of code that will accomplish what you are looking for
System.out.println(new BigInteger("10101010101010111101010101001101010101010101001010101010101001011101010101010101",2).toString());

How to always round in two decimals

For a project at school, I have to make a java program to retrieve data from a database.
This is my code:
import java.text.*;
import java.util.*;
public class Tijdstip
{
public Tijdstip()
{
}
public double testTijd(String tijdstip1)
{
// splitting the time
String[] tokens = tijdstip1.split("\\s+");
int hours = Integer.parseInt(tokens[0]);
int minutes = Integer.parseInt(tokens[1]);
//returning the time
double result = hours + ((double)minutes/100);
return result;
}
}
I fill in a time as string like: "7 10", meaning 7:10am and it must return a double like 7.10
But it returns 7.1, how do I make it so it will return 7.10 instead of 7.1?
You need to understand the difference between how a number is represented and how it is displayed. There is no numeric difference between 7.1 and 7.10; there is no way to make the number one instead of the other. You can display 7.1 as 7.10 using output formatting such as found in the Format class.
As a side issue: Storing this as a double would be a bad idea in a program of any size. There are many classes for representing time, and they all take into account the non-decimal nature of time divisions. Doubles don't do this.
Try this
new DecimalFormat("#.00").format(result);
The short answer is that you cannot do this if you must keep the result as a double. The double doesn't know anything about leading or trailing zeros. You can only do this when the result is formatted as a String. E.g., String.format("%.2f", 7.1) gives the string "7.10". You can easily do this formatting every time you display the number, but you cannot make the number itself remember the extra zero.
When you return double it will always truncate your last number if it is zero. so make it a string and return
If you need double value which has only two digits after dicimal, you can try following:
double d = 1.164444;
double r = Math.rint(d * 100)/100;
System.out.println(r);

Why does trying to parse this value result in a NumberFormatException?

Code:
String myVar = "1255763710960";
int myTempVar=0;
try
{
myTempVar = Integer.valueOf(myVar);
}
catch (NumberFormatException nfe)
{
System.out.println(nfe.toString());
}
Output:
java.lang.NumberFormatException:
For input string: "1255763710960"
I have absolutely no idea why this is.
The value you're trying to store is too big to fit in an integer. The maximum value for an Integer is 231-1, or about 2 billion. This number exceeds that by several orders of magnitude.
Try using a Long and parseLong() instead.
Java Integer maximun value is 2^31-1=2147483647
You should use Long.valueof()
Your String representation is too big (>Integer.MAX_VALUE) for parsing to an int. Try a long instead.
1255763710960 is more than Integer.MAX_VALUE which is 2147483647, so that value doesn't fit in an int.
You'll need to use a long and Long.valueOf() (or better yet Long.parseLong() to avoid unnecessary auto-unboxing) to parse that value.

Categories

Resources