How is it that System.out.println(052) and System.out.println(0x2a) both print 42?
Does this have to do with binary at all?
052 is an octal (base 8) literal.
0x2a is a hexadecimal (base 16) literal.
System.out.println(0x2a) uses a hex literal (0x prefix indicates this), which has a decimal equivalent of 42.
System.out.println(052) uses an octal literal (leading 0 indicates this), which has a decimal equivalent is 42.
System.out.println will print the integers according to their decimal representation. If you want to keep hex, try System.out.printf("%x\n", 0x2a), or, for octal, "%o" in place of "%x".
052, 0x2a and 42 are all different ways of writing the (decimal, base 10) number 42:
052 is octal, or base 8
0x2a is hexadecimal, or base 16
42 is the familiar decimal, base 10
java allows you to use numbers literally in your code using any of these different formats: using a leading 0x to specify hexadecimal, or a leading zero, 0 to specify octal.
This has to do with binary inasmuch as anything that you'll do with java has to do with binary.
By the way, the binary, base 2 representation of 42 is: 101010. You can also use binary literals in java by preceding them with 0b, so 0b101010 == 0x2a.
052, starts with 0, so it's an octal number and hence 8*5+2=42
0x2a starts with 0x, so it's a hexadecimal number and hence 16*2+a = 32 + 10=42
052 is an octal literal, and is equivalent to 0 * 8^2 + 5 * 8^1 + 2 * 8^0.
0x2a is a hexadecimal literal, equivalent to 2 * 16^1 + 10 * 16^0.
5 * 8 + 2 and 2 * 16 + 10 can be seen to be equivalent, as 5 * 8 is equivalent to 4 * 8 + 8, and 8 + 2 equals 10.
Related
Let's say we have a my_string = "123456"
I do
my_string.getBytes()
and
new BigInteger(123456).toByteArray()
The resulting byte arrays are different for both these cases. Why is that so? Isn't "123456" same as 123456 other than the difference in data type?
They are different because the String type is made up of unicode characters. The character '2' is not at all the same as the numeric value 2.
No. Why would they be? "123456" is a sequence of the ASCII character 1 (which is not represented as the number 1, but as the number 49), followed by the number 2 (50), and so on. 123456 as an int isn't even represented as a sequence of digits from 0-9, but it's stored as a number in binary.
I assume that you are asking about the total memory used to represent a number as a String versus a byte[].
The String size will depend on the actual string representation used. This depends on the JVM version; see What is the Java's internal represention for String? Modified UTF-8? UTF-16?
For Java 8 and earlier (with some caveats), the String consists of a String object with 1 int fields and 1 reference field. Assuming 64 bit references, that adds up to 8 bytes of header + 1 x 4 bytes + 1 x 8 bytes + 4 bytes of padding. Then add the char[] used to represent the characters: 12 bytes of header + 2 bytes per character. This needs to be rounded up to a multiple of 8.
For Java 9 and later, the main object has the same size. (There is an extra field ... but that fits into the "padding".) The char[] is replaced by a byte[], and since you are just storing ASCII decimal digits1, they will be encoded one character per byte.
In short, the asymptotic space usage is 1 byte per decimal digit for Java 9 or later and 2 bytes per decimal digit in Java 8 or earlier.
For the byte[] representation produce from a BigInteger, the represention consists of 12 bytes of header + 1 byte per byte ... rounded up to a multiple of 8. The asymptotic size is 1 byte per byte.
In both cases there is also the size of the reference to the representation; i.e. another 8 bytes.
If you do the sums, the byte[] representation is more compact than the String representation in all cases. But int or long are significantly more compact that either of these representations in all cases.
1 - If you are not ... or if you are curious why I added this caveat ... read the Q&A at the link above!
This question already has answers here:
Why are integer literals with leading zeroes interpreted strangely?
(8 answers)
Closed 5 years ago.
I have a short question about Datatypes. Why do i get this kind of number if i put a leading 0 for a number that i declared to be a long-type? I just dont get what the zero is making to the number.
For example:
1010L -> 1010
0101L -> 65
In Java integer literals with a leading zero are treated as octal by the compiler.
The leading zero is telling the computer to interpret the number as an octal.
In octal, base eight, the first one represents 64 in base ten, and the last one represents 1:
64 + 1 = 65 (base 10).
I think understand what they fundamentally do - operate on bits (flip, shift, invert, etc...).
My issue is that I don't know when I'd ever need to use them, and I don't think I fully understand bits.
I know that there are 8 bits in a byte and I know that bits are either a 0 or 1. Now here is where I start to get confused... I believe data types define combinations of bits differently. So if I declare an int, 32 bits are set aside for numbers, if I declare a char, 8 bits are set aside and the bits for that data type define a letter.
Running with that idea, I did the following basic operation in java which confuses me:
int num = 00000010;
System.out.println(num);
This prints 8 and if I define num this way:
int num = 00000100;
System.out.println(num);
This prints 64
So to practice with bitwise operations (just for the hell of it) I tried this:
int num = 00000010 << 1;
System.out.println(num);
And it prints 16 where as I thought it would shift the bits by one to the left and print 64.
What is happening here, and when would I ever need to apply this method of manipulating bits?
You are accidentally specifying an octal literal when you specify a number with a leading zero.
00000010 => 1*8^1 + 0*8^0 => 8
00000100 => 1*8^2 + 0*8^1 + 0*8^0 => 64
The JLS, Section 3.10.1, describes octal and binary literals:
An octal numeral consists of an ASCII digit 0 followed by one or more
of the ASCII digits 0 through 7 interspersed with underscores, and can
represent a positive, zero, or negative integer.
A binary numeral consists of the leading ASCII characters 0b or 0B
followed by one or more of the ASCII digits 0 or 1 interspersed with
underscores, and can represent a positive, zero, or negative integer.
You are bit-shifting your 8 by one to the left, effectively multiplying it by 2 to get 16. In bits:
00000100 => 00001000
(8 => 16)
Binary literals are expressed with leading 0b, e.g.:
0b000010 => 2
why,
System.out.println(Integer.parseInt("17", 8));
print out: 15
and,
System.out.printf("%o", 17);
print out: 21
Aren't they supposed to return octal value of 17?
Your first example converts the octal value 17 to decimal, which is 15.
Your second example converts the decimal value 17 to octal, which is 21.
If you modify your second example to use 017 (octal 17), you'll get the same result.
According to the Java API
parseInt(String s, int radix)
s - This is a string representation of decimal.
radix - This would be used to convert String s into integer.
So your Integer.parseInt("17", 8) will convert "17" to decimal using base value of 8 which is resulted 15
"%o" is use to format as Octal value so 17 will be represented as a Octal value. And result will be 21
So all the outputs that you get is correct.
System.out.printf("%o", 17);
This is used to convert an integer into its octal value
System.out.println(Integer.parseInt("17", 8));
This converts string(ocatal value) to integer.
1)
I understand that when you're converting binary to decimal the left most bit represents 0, 1...so on. So for example to convert 0001 to decimal it is 0*2^0+0*2^1+0*2^2+1*2^3 so the decimal value would be 8.
2)
When for example you have signed hex 0x80 which will be converted to binary 1000 0000 however in order to compute the decimal value for this binary representation it is signed so we have to invert 7 bits so we get 1111111 and add 1 which gives us 10000000 which is -128.
My question is why in the second case when we're computing the decimal for the signed byte we had to start from right most bits as 0 so we have ....+1*2^8. Why isn't the 2^0 the left most bit as we computed in 1) for the second case?
Thanks.
No, usually binary is stated the other way...0001 is 1, 1000 is 8.
I answer to point 1, not quite. 0001 is actually 1 while 1000 is 8. You appear to be coming from the wrong end. The binary number 1101, for example would be:
+------ 1 * 2^3 = 8
|+----- 1 * 2^2 = 4
||+---- 0 * 2^1 = 0
|||+--- 1 * 2^0 = 1
|||| --
1101 = 13
For point 2, the easiest way to turn a bit pattern into a signed number is to first turn it into an unsigned value (0x80 = 128), then subtract the bias (256 for eight bits, 65536 for 16 bits and so on) to get -128.
The bias should only affect the calculation at the end of the process, it's a way to map the range 0..255 to -128..127, or 0..65535 to -32768..32767.