It's quite straight forward in java to parse number from String, i.e. with Integer.parseInt(s) if string in the format 'n' or '-n', but unfortunately it fails to parse string in the format of '+n'.
So what is the most effective/elegant way to parse number from string in java if it contains positive or negative prefix: '+n' or '-n' ?
Integer.parseInt(s.replace("+", ""));
In truth there are many gotchas using Integer to parse numbers like that, in that Integer has very specific bounds of size and format ("1,000,000.00") isn't parsing that way, but I'm taking your question as Integer.parseInt meets your needs just fine, you just have to deal with a + in your data.
Just FYI, this has been fixed in Java 7.
from, Java SE8 for the Really Impatient
Prior to JDK 1.7, what was the result of the following code segment?
double x = Double.parseDouble("+1.0");
int n = Integer.parseInt("+1");
Pat yourself on the back if you knew the
answer: +1.0 has always been a valid floating-point number, but
until Java 7, +1 was not a valid integer. This has now been fixed
for all the various methods that construct int, long, short, byte,
and BigInteger values from strings. There are more of them than you
may think. In addition to parse (Int|Long|Short|Byte), there are
decode methods that work with hexadecimal and octal inputs, and
valueOf methods that yield wrapper objects. The BigInteger(String)
constructor is also updated.
Related
I'm using an Oracle DB together with JDBC. I have to select some values and write them to a file.
First I used ResultSet#getString which gave me almost all values formatted as desired except sometimes numbers were represented with an exponential. E.g.: 0.0897234E-4
In order to get rid of the exponential I checked if the type of the current column is NUMERIC and then used ResultSet#getBigDecimal to get a BigDecimal. I've done that because there are all kinds of Java number types stored in the DB and as Oracle DB only provides NUMERIC as type for numbers, I have to use the BigDecimal because every numeric Java type can be stored in a BigDecimal.
Then I used the BigDecimal#toPlainString method to effectively get rid of the exponential.
if (rset.getMetaData().getColumnType(i) == java.sql.Types.NUMERIC) {
value = (rset.getBigDecimal(i) != null rset.getBigDecimal(i).toPlainString() : "0");
}
The next problem was, that I then got a leading zero when the number was below 1 but I don't want them.
Before .007346 <-- desired
After 0.007346
Before -.4352 <-- desired
After -0.4352
To deal with that problem I searched the internet and found the DecimalFormat class. I was then able to format the numbers so that I don't have leading zeros with the following format:
new DecimalFormat("#.");
But this of course didn't display any digits after the decimal point but does add a decimal point after every number. E.g.: 1235. -65.
So what I want is, that if the number is decimal there should be as much digits as needed (actually 38, I think is in Oracle DB the max). There should never be exponentials and if the number is below 1 there shouldn't be a leading zero. If the number is natural there shouldn't be a decimal point at the end.
Some examples of the desired format:
9873478 -1349 .743803 -.004726
How can I achieve such a representation? Any solution is welcome I don't have to use the DecimalFormat. Could the solution possibly be, that I have to determine the type after getting the number as a BigDecimal by trying to convert it to the different Java types?
What about new DecimalFormat(".#");?
You were very close to the answer, indeed. As you can see the behaviour of the decimals in your attempt is the behaviour you expected on the integer part.
As you can read in Javadoc # shows zero as absent
EDIT
As stated in the comments, the problem with the solution above is that you get only one decimal. You'd maybe better define your layout by the API rather than with a pattern.
DecimalFormat format = new DecimalFormat();
format.setMinimumIntegerDigits(0);
format.setMaximumFractionDigits(2000);//should be more than enough
Note that you could also improve the first solution
DecimalFormat format = new DecimalFormat(".##################################################################");
...but it is less easy to define a large number of fraction digits (if you really need it).
The following expressions are valid in Java as obvious
int a = -0;
int b = +0;
and so are the following.
Integer c = new Integer(-0);
int d = Integer.parseInt("-0");
BigDecimal e = new BigDecimal("-0");
The following statements are however invalid.
Integer f = new Integer("+0"); //Leading + sign.
int g=Integer.parseInt("+0"); //Leading + sign.
Both of them throw the NumberFormatException.
The following statement with BigDecimal however compiles and runs without causing an exception to be thrown.
BigDecimal bigDecimal = new BigDecimal("+0"); //Leading + sign.
Why is a leading + sign valid with BigDecimal here which however doesn't appear to be the case with the other datatypes available in Java?
According to the documentation, negative signs needs the minus sign. But if its a positive Integer, no need for a plus sign.
public static int parseInt(String s)
The characters in the string must all be decimal digits, except that
the first character may be an ASCII minus sign '-' ('\u002D') to
indicate a negative value. The resulting integer value is returned,
exactly as if the argument and the radix 10 were given as arguments to
the parseInt(java.lang.String, int) method.
Then for the constructor:
public Integer(String s)
The string is converted to an int value in exactly the manner used by the parseInt method for radix 10.
The real answer is most likely that the inconsistent behaviour between new Integer("+0") and new BigDecimal("+0") is a result of a mistake in design of one or the other. Unfortunately, the mistake got "baked on" when the relevant class was publicly released, and Sun / Oracle were unwilling to fix it because:
the respective implementations do conform to their respective specifications,
the inconsistency is a relatively minor issue with a simple work-around, and
fixing it is likely to break forwards and backwards compatibility.
(And this explanation is supported by the evaluation section of Java Bug #4296955 that #rlay3 found!!)
Note that I have excluded your Java expression examples from consideration. That is because the context for Java expression syntax and converting text strings are sufficiently different that (IMO) you should not expect them to behave the same. (And in the same way, you should not expect a String reader to do something special with any \ characters that it encounters ...)
UPDATE
#ADTC has observed that they actually did change this in Java 7 and that Integer.parseInt now does accept a leading + sign.
The corresponding Java bug for this enhancement is #5017980. (And if you look at the linked bugs, the first one seems to imply that the change has been backported to OpenJDK6.)
However, Oracle didn't mention this change in the Java 7 compatibility / upgrade documents ... which is strange given that Sun had previously rejected the change because of compatibility concerns!!
This is all rather peculiar ...
I want to sum the values of four columns of a recordstore. The values in these four columns are numbers with the decimal point , for example 30.00; the recordstore row is a csv-like data with which I use a userdefined function to get the value of a particular column: so I get a String for the four columns , for example "30.00". Now I want to sum these four values ; so I must convert them into int ! But when I attempt to use Integer.parseInt then the java.lang.NumberFormatException is raised ! So how to make the sum in this situation ?
Even though 30.00 seems like an integer to you, Java thinks it looks like a floating point value (due to the decimal point).
You therefore need to parse it as a double, and then get the integer part.
int i = Double.parseDouble("30.00").intValue();
(Not J2ME specific by the way.)
If your numbers contain decimal points, you need to parse as a double.
Double.parseDouble("30.00");
From there you can use Math methods or just truncate to get your Integer.
Just as another alternative, you could also use Integer.parseInt("30.00".split("\\.")[0])This would remove dependency on decimal separator (if you always have a dot in string, but you have no control on locale it will be parsed on.
I have a Objective C code,which I have to translate in Java,but I have a little problem with converting one line. In Objective C code I have : UInt64 iz = strtoull(s,&s1,16);. I was searching over the internet abotu strtoull and I find this information for it :
strtoul will convert a string to an unsigned long integer. An
important feature of this function is the ability to accept data in
various number bases and convert to decimal.
The first argument must not contain a + or -. The second argument
(char **endptr) seems to be a waste of space! If it is set to NULL,
STRTOL seems to work its way down the string until it finds an invalid
character and then stops. All valid chars read are then converted if
the string starts with an invalid character the function returns ZERO
(0).
The Third argument (base) can have a value of 0 or 2-32.
0 - strtol will attempt to pick the base. Only Dec, Oct Hex supported.
2-31 - The base to use.
I tried to find a way to do this in Java.As a made some researches I got this :
long l=Long.parseLong(md5Hash, 16);
And my question is,is parseLong equivalent to strtoull and can I use it for my application? If not can you suggest me what can I use?
Thanks in advance!
You can't because long is signed in Java. If you need unsigned integers for the full value range of 64 Bit then you have to use the BigInteger class.
Long.parseLong is the usual way of parsing a string into a long. But be aware that Java does not have unsigned types.
It is equivalent but keep in mind that long in Java is not unsigned. Therefore, a Java long is in [-2^63, 2^63 - 1].
use
BigInteger(String val, int radix)
I have big problem with reading big numbers from excel in java. When i read 71674705 i get 7.1674705E which is not ok.
Example:
double num =
cell.getNumericCellValue();
how can i prevent conversion between numbers that number will stay like 71674705.
The number itself is not changing, only the representation when you convert it to a String. A double variable like you are using does not have an explicit format defined.
You can use java.text.NumberFormat (javadoc) to format the number any way you would like to see it.
num is just a double, i.e. a binary floating-point number. That formatting (exponential notation) is only an issue for printing. So if you're just debugging, you shouldn't have to worry. For production output, you can use a NumberFormat such as DecimalFormat.
If you are sure you are dealing with an integer and you want it as an integer value you can always try to do:
Integer.valueOf(num)
Edit: not valid for big numbers of course :-)