Converting characters to integers in Java - java

Can someone please explain to me what is going on here:
char c = '+';
int i = (int)c;
System.out.println("i: " + i + " ch: " + Character.getNumericValue(c));
This prints i: 43 ch:-1. Does that mean I have to rely on primitive conversions to convert char to int? So how can I convert a Character to Integer?
Edit: Yes I know Character.getNumericValue returns -1 if it is not a numeric value and that makes sense to me. The question is: why does doing primitive conversions return 43?
Edit2: 43 is the ASCII for +, but I would expect the cast to not succeed just like getNumericValue did not succeed. Otherwise that means there are two semantic equivalent ways to perform the same operation but with different results?

Character.getNumericValue(c)
The java.lang.Character.getNumericValue(char ch) returns the int value that the specified Unicode character represents. For example, the character '\u216C' (the roman numeral fifty) will return an int with a value of 50.
The letters A-Z in their uppercase ('\u0041' through '\u005A'), lowercase ('\u0061' through '\u007A'), and full width variant ('\uFF21' through '\uFF3A' and '\uFF41' through '\uFF5A') forms have numeric values from 10 through 35. This is independent of the Unicode specification, which does not assign numeric values to these char values.
This method returns the numeric value of the character, as a
nonnegative int value;
-2 if the character has a numeric value that is not a nonnegative integer;
-1 if the character has no numeric value.
And here is the link.

As the documentation clearly states, Character.getNumericValue() returns the character's value as a digit.
It returns -1 if the character is not a digit.
If you want to get the numeric Unicode code point of a boxed Character object, you'll need to unbox it first:
int value = (int)c.charValue();

Try any one of the below. These should work:
int a = Character.getNumericValue('3');
int a = Integer.parseInt(String.valueOf('3');

From the Javadoc for Character#getNumericValue:
If the character does not have a numeric value, then -1 is returned.
If the character has a numeric value that cannot be represented as a
nonnegative integer (for example, a fractional value), then -2 is
returned.
The character + does not have a numeric value, so you're getting -1.
Update:
The reason that primitive conversion is giving you 43 is that the the character '+' is encoded as the integer 43.

43 is the dec ascii number for the "+" symbol. That explains why you get a 43 back.
http://en.wikipedia.org/wiki/ASCII

public class IntergerParser {
public static void main(String[] args){
String number = "+123123";
System.out.println(parseInt(number));
}
private static int parseInt(String number){
char[] numChar = number.toCharArray();
int intValue = 0;
int decimal = 1;
for(int index = numChar.length ; index > 0 ; index --){
if(index == 1 ){
if(numChar[index - 1] == '-'){
return intValue * -1;
} else if(numChar[index - 1] == '+'){
return intValue;
}
}
intValue = intValue + (((int)numChar[index-1] - 48) * (decimal));
System.out.println((int)numChar[index-1] - 48+ " " + (decimal));
decimal = decimal * 10;
}
return intValue;
}

Related

How to convert a String to an integer without losing preceding zeroes in Java?

I am trying to convert a String with preceding zeroes into an integer (or, let's say, a BigDecimal). But the zeroes are truncated when the String is converted. Please help me to convert without losing zeroes.
Here Oracle explains how integers are stored.
int, whose values are 32-bit signed two's-complement integers, and whose default value is zero
and also
The values of the integral types of the Java Virtual Machine are:
For int, from -2147483648 to 2147483647 (-2^31 to 2^31 - 1), inclusive
show that they only store the number, with 32 bits you can only store where you are in the range of -2147483648 to 2147483647.
So integers don't contain information about preceding zeroes. You had to store it separately.
String s = "0002314";
int precedingZeroes = 0;
for (char c : s.toCharArray()) {
if(c == '+' || c == '-') {
// Allowed, but no zero -> continue
continue;
}
if(c == '0') {
zeroes++; // We found a zero, increment counter
continue;
}
// This is not a sign and no zero; we have non-zero digits now
// (or it would be an ill-formed integer) so the other zeroes
// are no preceding ones; -> break the loop, that's it
break;
}
int number = Integer.parseInt(s);
So you have to store both the number and the number of zeroes. Note that this only works for decimal numbers.

Simple math issue?

For simplicity's sake, I've got the following method to calculate whether the number inputted is binary (only accepts 1's and 0's)
public static void checkBinary(int BinaryNumber) {
String bNumber = String.valueOf(BinaryNumber);
char[] Digits = bNumber.toCharArray();
for (int i = 0; i < Digits.length; i++) {
if (Digits[i] > 1) {
System.out.println("You can't have the digit " + Digits[i]);
System.out.println("Your number is not a binary number.");
System.exit(0);
}
}
}
However when I try running checkBinary(1010); I get the following output
You can't have the digit 1
Your number is not a binary number.
Any idea why it's counting the initial 1 as greater than 1?
Thanks in advance guys!
ASCII '1' is not the same as 1. You should be comparing:
if (Digits[i] > '1') {
...
}
ASCII '1' is 0x31 or 49 decimal.
EDIT: also, be aware that if the input number is negative, you will have an ASCII '-' (0x2d, dec 45) in your char array. Really, you should be comparing against '0' and '1' only, not using >
try comparing character with character, not a number. Changing your comparision to:
Digits[i] > '1'
Will fix this code.
"1" representation in ASCII code has decimal value of 49, as presented in following table:
You are confusing numbers with representations of numbers. It makes no sense to ask if '0' or '1' are greater than one. '0' and '1' are digits and one is a numerical value.
Digits: '0' is a digit. '1' is a digit. "Three" is not a digit. Digits are symbols that can express a number, or part of a number, in some particular base.
Numbers: '0', "zero", and "one less than one" all mean the same thing, they're the same number. Numbers are amounts and can be represented many different ways, including by sequences of digits.
Thoroughly understanding the difference between values and representations of values is a critical programming skill.
Digits[i] is char, you comparing it with 1 (as integer).
You need to you use
Integer.valueOf(Digits[i])
instead.
Because Digits[i] equals 49, which is greater than 1.
You're using characters, not numbers:
char[] Digits = bNumber.toCharArray();
When you compare a char to an int, the char is implicitly converted to an int using the integer value of that character. And the integer value of '1' is 49.
A simple approach would be to use characters in both sides of the comparison:
if (Digits[i] > '1')
Or maybe use the intuitive numeric value of the char:
if (Character.getNumericValue(Digits[i]) > 1)
Here is the issue: if (Digits[i] > 1)
You are comparing char to an int. You should probably change this logic. Either compare char to char or int to int.
In java Characters equals to ASCII code, so you should change your if statement in your function like that:
public static void checkBinary(int BinaryNumber) {
String bNumber = String.valueOf(BinaryNumber);
char[] Digits = bNumber.toCharArray();
for (int i = 0; i < Digits.length; i++) {
if (Character.getNumericValue(Digits[i]) > 1) {
System.out.println("You can't have the digit " + Digits[i]);
System.out.println("Your number is not a binary number.");
System.exit(0);
}
}
}

charvariable=(char)(charvariable+3) what does this syntax mean?

I have been looking around on the internet at caesar ciphers and while I understand the loop I don't understand why this line of code is able to shift a char to another char? I don't understand this line here:
letter = (char)(letter - 26);
When I take (char) out it doesn't work and I have never seen it with the type being in parentheses followed by an operation.
Hopefully this is an easy question and thanks for the help.
for (int i = 0; i < buffer.Length; i++)
{
// Letter.
char letter = buffer[i];
// Add shift to all.
letter = (char)(letter + shift);
// Subtract 26 on overflow.
// Add 26 on underflow.
if (letter > 'z')
{
//The following line is the line I don't understand. Why char in parentheses then another parentheses?
letter = (char)(letter - 26);
}
else if (letter < 'a')
{
letter = (char)(letter + 26);
}
// Store.
buffer[i] = letter;
}
(char) is a cast. That means that it takes a value which is of one type, and converts it to a value of another type. Thus, if x is an int, (double)x yields a double whose value is the same value as the integer value.
The reason (char) is necessary in this expression is that Java does all its integer arithmetic on values of type int or long. So even though letter is a char, in the expression letter + 26, letter will be automatically converted to an int, and then 26 is added to the integer. (char) converts it back to a char type (which is an integer value from 0 to 65535). Java will not automatically convert a larger integer type (int, whose values are from -2147483648 to 2147483647) to a shorter integer type (char), therefore it's necessary to use a cast.
However, Java does allow this:
letter += 26;
which has the same effect, and does not require a cast.
There are 26 letters in the english alphabet, and char is an integral type
char ch = 'Z' - 25;
System.out.println(ch); // <-- A
JLS-4.2.1 - Integral Types and Values says (in part),
For char, from '\u0000' to '\uffff' inclusive, that is, from 0 to 65535

Binary Representation to a new byte

I'm trying to create a new byte knowing a certain amount of bits
char prostie1 = theRepChars[j-3];
char prostie2 = theRepChars[j-2];
char prostie3 = theRepChars[j-1];
char prostie4 = theRepChars[j];
String prostiaMare = prostie4 + prostie3 + prostie2 + prostie1 + "";
Byte theChar = new Byte(prostiaMare);
When i do this I get a NumberFormatException value 196.
I have no idea what might be my problem
--EDIT--
Ok I think I might have to give some more details since I wasn't very clear. I'm trying to do an Uuencode algorithm and by following the logic of the algorithm I should stop my byte having a value bigger than 194. Here is a bunch of my code.
if(my_chars.length % 3 == 0)
{
for(int x = 0; x < my_chars.length; x++)
{
if((x+1) % 3 == 0)
{
char first = my_chars[x-2];
char second = my_chars[x-1];
char third = my_chars[x];
int n = (((first << 8) | second) << 8) | third;
String theRep = Integer.toBinaryString(n);
while(theRep.length() < 24 - 1)
{
theRep = 0 + theRep;
}
//0 padded theRep
for(int j = 0; j < theRepChars.length; j++)
{
if((j+1) % 4 == 0)
{
char prostie1 = theRepChars[j-3];
char prostie2 = theRepChars[j-2];
char prostie3 = theRepChars[j-1];
char prostie4 = theRepChars[j];
String prostiaMare = prostie4 + prostie3 + prostie2 + prostie1 + "";
System.out.println(prostiaMare);
}
}
}
}
}
And trying to create a new byte with the value that prostiaMare has gives me the numberFormatException. I'm not sure if I have not followed the algorithm right ( http://www.herongyang.com/encoding/UUEncode-Algorithm.html )
196 is outside the range of byte, a signed value. Bytes can range from -128 to 127.
I'm not sure why you're casting to String. If you just want a byte with bits equivalent those of the sum of the four chars, cast directly to byte:
(byte) (prostie4 + prostie3 + prostie2 + prostie1)
If you intended to construct a String from the four chars, you are not currently doing that. Use:
"" + prostie4 + prostie3 + prostie2 + prostie1
and, if the result is in the range of a byte, you can create a byte as you have been.
Bytes are signed in Java. Which means a byte, which is 8 bits long, has a minimum value of -2^7 (-128) and a max value of 2^7 - 1 (127). Java has no unsigned primitive types apart from char (unsigned, 16bit).
Therefore 196 is unparseable --> NumberFormatException.
You don't have much to work around this except to read into a larger type and do & 0xff to obtain the byte:
final int i = Integer.parseInt(theString);
final byte b = (byte) (i & 0xff);
Or do yourself a favour and use Guava, which has UnsignedBytes:
final byte b = UnsignedBytes.parseUnsignedByte(theString);
But it appears that you want to do comparisons anyway; so just use a larger type than byte. And no, this won't waste memory: don't forget about alignment.
As mentioned in the docs
An exception of type NumberFormatException is thrown if any of the following situations occurs:
The first argument is null or is a string of length zero.
The radix is either smaller than Character.MIN_RADIX or larger than Character.MAX_RADIX.
Any character of the string is not a digit of the specified radix, except that the first - character may be a minus sign '-' ('\u002D') provided that the string is longer than length 1.
The value represented by the string is not a value of type byte.
In your case its the last case since 196 cant be represented as byte..The valid range is -128 to 127

Why doesn't my compare work between char and int in Java?

char c = '0';
int i = 0;
System.out.println(c == i);
Why does this always returns false?
Although this question is very unclear, I am pretty sure the poster wants to know why this prints false:
char c = '0';
int i = 0;
System.out.println(c == i);
The answer is because every printable character is assigned a unique code number, and that's the value that a char has when treated as an int. The code number for the character 0 is decimal 48, and obviously 48 is not equal to 0.
Why aren't the character codes for the digits equal to the digits themselves? Mostly because the first few codes, especially 0, are too special to be used for such a mundane purpose.
The char c = '0' has the ascii code 48. This number is compared to s, not '0'. If you want to compare c with s you can either do:
if(c == s) // compare ascii code of c with s
This will be true if c = '0' and s = 48.
or
if(c == s + '0') // compare the digit represented by c
// with the digit represented by s
This will be true if c = '0' and s = 0.
The char and int value can not we directly compare we need to apply casting. So need to casting char to string and after string will pars into integer
char c='0';
int i=0;
Answer is like
String c = String.valueOf(c);
System.out.println(Integer.parseInt(c) == i)
It will return true;
Hope it will help you
Thanks
You're saying that s is an Integer and c (from what I see) is a Char.. so there you, that's the problem: Integer vs. Char comparation.

Categories

Resources