Java - Construct a signed numeric String and convert it to an integer - java

Can I somehow prepend a minus sign to a numeric String and convert it into an int?
In example:
If I have 2 Strings :
String x="-";
String y="2";
how can i get them converted to an Int which value is -2?

You will first have to concatenate both Strings since - is not a valid integer character an sich. It is however acceptable when it's used together with an integer value to denote a negative value.
Therefore this will print -2 the way you want it:
String x = "-";
String y = "2";
int i = Integer.parseInt(x + y);
System.out.println(i);
Note that the x + y is used to concatenate 2 Strings and not an arithmetic operation.

Integer.valueOf("-") will throw a NumberFormatException because "-" by itself isn't a number. If you did "-1", however, you would receive the expected value of -1.
If you're trying to get a character code, use the following:
(int) "-".charAt(0);
charAt() returns a char value at a specific index, which is a two-byte unicode value that is, for all intensive purposes, an integer.

Related

What happens when you use arithmetic operators inside of a string declaration?

If there is an arithmetic operator inside of a string declaration, how does the String treat the operator?
For example in this case:
String s = "de32";
s = s.charAt(0) * 2 + "";
System.out.println(s);
String s is not dd but instead is 102. What is the * 2 mean for the string?
s.charAt(0) is a char ('d'), and char is a numeric type. The numeric value of the character 'd' is 100. Therefore s.charAt(0) * 2 simply multiplies that value by 2, which results in 200 (not 102 as you wrote).
Then the result is converted to a String, since you appended to it an empty String, so s is assigned "200".
The expression is evaluated left to right, so it is equivalent to:
s = (s.charAt(0) * 2) + "";
First the char 'd' is promoted to an int and multiplied by 2.
Then the resulting int (200) is appended to the empty String "". resulting in the String "200".
At 0 position char d is there and it is multiplied with 2. So ASCII value of d is multiplied by 2. Since ASCII value of d is 100 so it gives result 200. Then it is appended to empty string and give "200" as a string .

Convert float to string and always get specific length of string?

How can I convert a float to a String and always get a resulting string of a specified length?
For example, if I have
float f = 0.023f;
and I want a 6 character string, I'd like to get 0.0230. But if I want to convert it to a 4 character string the result should be 0.02. Also, the value -13.459 limited to 5 characters should return -13.4, and to 10 characters -13.459000.
Here's what I'm using right now, but there's gotta be much prettier ways of doing this...
s = String.valueOf(f);
s = s.substring(0, Math.min(strLength, s.length()));
if( s.length() < strLength )
s = String.format("%1$-" + (strLength-s.length()) + "s", s);
From java.util.Formatter documentaion: you can use g modifier, precision field to limit number to specific number of characters and width field for padding it to column width.
String.format("%1$8.5g", 1000.4213);
https://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html
Though precision doesn't include dot and exponent length – only digits in mantissa counted.
By keeping extra place for dot and cutting extra digits from fractional part if string is significantly wider that could be solved too.
String num = String.format("%1$ .5g", input);
if (num.length > 6)
num = num.substring(0, 2) + num.substring(7); //100300 => ' 1e+05'; 512.334 => ' 512.33'
Scientific format of number always follows strict set of rules, so we don't have to search for dot inside string to cut fraction out of string if sign is always included (or, like in case above – replaced by space character for positive numbers).

Converting Hex in Java, wrong value with negative values

I have seen several questions on the topic mentioned in the subject (e.g this one), but it seems to me that none of them provided this example. I'm using Java7 and I want to convert a String representing an hexadecimal or a decimal into an Integer or Long value (depends on what it represents) and I do the following:
public Number getIntegerOrLong(String num) {
try {
return Integer.decode(num);
} catch (NumberFormatException nf1) {
final long decodedLong = Long.decode(num);
if ((int) decodedLong == decodedLong) {//used in Java8 java.util.Math.toIntExact()
return (int) decodedLong;
}
return decodedLong;
}
}
When I use a String representing a decimal number everything is ok, the problem are arising with negative hexadecimals
Now, If I do:
String hex = "0x"+Integer.toHexString(Integer.MIN_VALUE);
Object number = getIntegerOrLong(hex);
assertTrue(number instanceof Integer):
fails, because it returns a Long. Same for other negative integer values.
Moreover, when I use Long.MIN_VALUE like in the following:
String hex = "0x"+Integer.toHexString(Long.MIN_VALUE);
Object number = getIntegerOrLong(hex);
assertTrue(number instanceof Long):
fails, because of NumberFormatException with message:
java.lang.NumberFormatException: For input string: "8000000000000000"
I also tried with other random Long values (so within the Long.MIN_VALUE and Long.MAX_VALUE, and it fails as well when I have negative numbers. E.g.
the String with the hexadecimal 0xc0f1a47ba0c04d89 for the Long number -4,543,669,698,155,229,815 returns:
java.lang.NumberFormatException: For input string: "c0f1a47ba0c04d89"
How can I fix the script to obtain the desired behavior?
Long.decode and Integer.decode do not accept complemented values such as returned by Integer.toHexString : the sign should be represented as a leading - as described by the DecodableString grammars found in the javadoc.
The sequence of characters following an optional sign and/or radix specifier ("0x", "0X", "#", or leading zero) is parsed as by the Long.parseLong method with the indicated radix (10, 16, or 8). This sequence of characters must represent a positive value or a NumberFormatException will be thrown. The result is negated if first character of the specified String is the minus sign
If you can change the format of your input String, then produce it with Integer.toString(value, 16) rather than Integer.toHexString(value).
If you can switch to Java 8, use parseUnsignedInt/Long.

Get the previous and next values of a string

I am using a NoSQL database which doesn't allow equality conditions of attributes that are projected. Eg Unequality operations such as select a from table where a > 10 and is allowed select a from table where b < 10, but select a from table where a = 10 is not allowed. Of course I need to use an equality in my case, so I want to turn a equality operations into an inequality operation.
So I need to retrieve a record by email. If could I would go select email from table where email = 'myemail#email.com', but this is not allowed so I want to get the lexicographic value right before myemail#email.com and the value right after. So the query would look like this:
select email from table where email < [1 value above] and email > [1 value below]
This way the statement would still return myemail#email.com. I am having trouble though how to accomplish this.
Usually to compare strings I go "myemail#email.com".compare("myemail#email.ca") to see which one bigger and which one is smaller. This method compares the values somehow based on lexicographic, but how? My question is how to get the lexicographic value right below a string and the lexicographic value right after the string?
The string immediately after a string is easy. It's just
str + '\0'
This works because '\0' is the lowest possible char value.
The string immediately before str is more tricky. If the string ends in '\0' you can just remove it. If the string doesn't end in '\0' you have serious issues. As an example, let's consider the string "foo".
Each of the following strings is below "foo" and each one is bigger than the last.
"fon" + Character.MAX_VALUE;
"fon" + Character.MAX_VALUE + Character.MAX_VALUE;
"fon" + Character.MAX_VALUE + Character.MAX_VALUE + Character.MAX_VALUE;
...
The largest String value less than "foo" is "fon" followed by something like 2^31 - 4 copies of Character.MAX_VALUE (this may not be right. I'm not sure what the largest possible length of a char[] is). However, you will not be able to store such a string in memory.
You should therefore try to find an different solution to your problem.
Assuming your alphabet is a-z0-9, and case-insensitive, you can treat your string as a base-36 number and simply increment/decrement the values using simple arithmetic.
Java's Long.valueOf method allows you to take a String with a given radix, and convert it to it's (base 10) Long equivalent. Once you have a Long instance, you can simply add 1 to get the next value.
public static String nextString(String str) {
return Long.toString(Long.valueOf(norm(str), 36) + 1, 36);
}
To reverse the operation, you can use the Long.toString method, which takes a long instance and converts it to a String representation, with a specified radix. So you can represent your base-10 long as a base-36 number, which will include the letters a-z.
public static String prevString(String str) {
return Long.toString(Long.valueOf(norm(str), 36) - 1, 36);
}
You'll want to normalize your strings when using these methods, so this will filter our invalid characters, ensure that everything is lower-case, and prevent null pointer exceptions or number format exceptions.
private static String norm(String str) {
if (str == null) {
return "0";
}
return str.toLowerCase().replaceAll("[^a-z0-9]", "");
}

Converting leading 0 String into Integer in java

I have following string in my java class
String str="0000000000008";
Now I want to increment that so that the next value should be 0000000000009
For that purpose, I tried to cast this String str into Integer
Integer i=Integer.parseFloat(str)+1;
and when I print the value of i it prints only 17(as it removes the leading 0's from string at the time of cast).
How can I increment the String value, so that the leading 0's will remain, and the series will continue?
Practical solution - use String.format:
str = String.format("%013d", Long.parseLong(str)+1);
You are on the correct path. First parse to Long:
long cur = Long.parseLong("0000000000008");
increment and format back to String with leading 0s:
new java.text.DecimalFormat("0000000000000").format(cur + 1);
or alternatively:
String.format("%013d", Long.valueOf(cur));

Categories

Resources