I have Int class, I split it into 4 bytes using ByteBuffer.allocate(4).order(ByteOrder.BIG_ENDIAN).putInt(word).array(). Now, I would like to map through values of that bytes as bytes.map(w => w.toInt/16). Here I would like to have values being divided by 16 and get values in range of [0, 16] (as w is 1 byte). However, if value of w is something like 0xcc, I am getting -4 instead of 12.
I am currently using (BigInt(Array[Byte](0, w))/16).toInt but feel like it is quite slow and not idiomatic way of writing Scala code.
I tried using w >>> 4 but the result is some large integer.
In your case w >>> 4 is the right answer but by printing numbers as signed decimals you aren't seeing it.
On JVM all numbers, Byte and Int including, are signed. That's why you can see negative bytes. JVM's byte's range is -128 to 127 (8 bits, 2-complementary representation).
If you are dividing (/) you're doing slightly different operation than bit shifting (>>>) which shows when the first bit is on and the number is negative.
If you want to perform bit-wise operations, I would suggest working with methods like:
java.lang.Byte.toUnsignedInt(byte: Byte) to convert Byte to unsigned int (notice that it would be converted as unsigned int, the resulting Int would be pretty much signed for any numerical operation on JVM! Make sure that this conversion won't break anything by printing the values before and after conversion!)
f"0x${value}%02X" or java.lang.Integer.toHexString(value) - to print bytes
avoiding numerical operators like +, -, / and * and stick to binary operators (&, |, >>, >>>, and so on)
and not trust the numbers in their default, signed decimal print, because it might be confusing:
// REPL examples
// 1000 0000 0000 0000 0000 0000 0000 0000 (-2147483648)
# java.lang.Integer.toHexString(Int.MinValue)
res1: String = "80000000"
// 0111 1111 1111 1111 1111 1111 1111 1111 (2147483647)
# java.lang.Integer.toHexString(Int.MaxValue)
res2: String = "7fffffff"
// 1111 1111 1111 1111 1111 1111 1111 1111 (-1)
# java.lang.Integer.toHexString(Int.MinValue | Int.MaxValue)
res3: String = "ffffffff"
// 0000 0000 0000 0000 0000 0000 0000 0000 (0)
# java.lang.Integer.toHexString(Int.MinValue & Int.MaxValue)
res4: String = "0"
// 1000 0000 (-128)
# f"0x${Byte.MinValue}%02X"
res5: String = "0x80"
// 0111 1111 (127)
# f"0x${Byte.MaxValue}%02X"
res6: String = "0x7F"
// 1111 1111 (-1)
# f"0x${Byte.MinValue | Byte.MaxValue}%02X"
res7: String = "0xFFFFFFFF"
// 0000 0000 (0)
# f"0x${Byte.MinValue & Byte.MaxValue}%02X"
res8: String = "0x00"
I would say that low-level operations are kinda-specific so write whatever way is most readable - I wouldn't bother with making such code idiomatic, as long as I could make it easy to maintain. Just make sure to justify properly why you are working with an error-prone low-lever stuff rather than using existing high-level components. And don't make assumptions about the speed without benchmarks.
Converting Int into 4 bytes could also be done like:
val int: Int = ...
val mask = Integer.parseInt("1111", 2)
// not all of these are necessary but I wrote it like that for consistency
val b1 = (int >>> 12) & mask
val b2 = (int >>> 8) & mask
val b3 = (int >>> 4) & mask
val b4 = (int >>> 0) & mask
Related
I am following along my Scala textbook and I see this:
scala> val hex = 0x5
hex: Int = 5
scala> val hex2 = 0x00ff
hex2: Int = 255
scala> val hex3 = 0xff
hex2: Int = 255
scala> var hex4 = 0xbe
magic: Int = 190
scala> var hex5 = 0xFF
magic: Int = 255
val magic = 0xcafebabe
magic: Int = -889275714
scala> var prog = 0xCAFEBABEL
prog: Long = 3405691582
scala> val tower = 35l
tower: Long = 35
My questions:
why do you need the extra 00 after the x in 0x00FF?
I get why FF = 255... hexadecimal is base16 starting at 00 = 0 and 0F = 15. But why does 0xcafebabe = -889275714?
Why is going on with the Longs? I don't understand what is going on?
You don't, it's just to show that leading 0s are ignored as far as I can tell
int is a 32-bit signed integer: if you exceed 2^31, the highest-value bit gets set but is interpreted as a minus. In short, you have an overflow.
If you add "l", the variable is a long which uses 64 bits, so the overflow doesn't happen
00FF needs the 2 zeros to make sure that this is a SIGNED number, proving that it is positive by using the two zeros.
The cafebabe doesn't have that since it is a negative number. We found that out because of the lack of zeros at the end.
Finally, the point of the long (though im not sure of that one) is to set the idea that there are unseen zeros stretching backwards, thus giving us a positive number.
I need to sign-extend an 8bit value to 12 bits. In C, I can do it this way. I read Apple's BinaryInteger protocol documentation, but it didn't explain sign extending to a variable number of bits (and i'm also pretty new at Swift). How can I do this in Swift, assuming val is UInt8 and numbits is 12?
#define MASKBITS(numbits) ((1 << numbits) - 1)
#define SIGNEXTEND_TO_16(val, numbits) \
( \
(int16_t)((val & MASKBITS(numbits)) | ( \
(val & (1 << (numbits-1))) ? ~MASKBITS(numbits) : 0) \
))
You can use Int8(bitPattern:) to convert the given unsigned
value to a signed value with the same binary representation,
then sign extend by converting to Int16, make unsigned again, and finally truncate
to the given number of bits:
func signExtend(val: UInt8, numBits: Int) -> UInt16 {
// Sign extend to unsigned 16-bit:
var extended = UInt16(bitPattern: Int16(Int8(bitPattern: val)))
// Truncate to given number of bits:
if numBits < 16 {
extended = extended & ((1 << numBits) - 1)
}
return extended
}
Example:
for i in 1...16 {
let x = signExtend(val: 200, numBits: i)
print(String(format: "%2d %04X", i, x))
}
Output:
1 0000
2 0000
3 0000
4 0008
5 0008
6 0008
7 0048
8 00C8
9 01C8
10 03C8
11 07C8
12 0FC8
13 1FC8
14 3FC8
15 7FC8
16 FFC8
I had the same question in the context of bitstream parsing. I needed code to parse n bit two's complement values into Int32. Here is my solution that works without any condition:
extension UInt32 {
func signExtension(n: Int) -> Int32 {
let signed = Int32.init(bitPattern: self << (32 - n))
let result = signed >> (32 - n)
return result
}
}
And a unit test function showing how to use that code:
func testSignExtension_N_2_3() {
let unsignedValue: UInt32 = 0b110
let signedValue: Int32 = unsignedValue.signExtension(n: 3)
XCTAssertEqual(signedValue, -2)
}
I was wondering about this-
If A, B are 16-bit numbers and C is 8-bit, how many bits would I need to store the result ? 32 or 33 ?
And, what if C was a 16-bit number? What then ?
I would appreciate if I got answers with an explanation of the hows and whys.
Why don't you just take the maximum value for each register, and check the result?
If all registers are unsigned:
0xFFFF * 0xFFFF + 0xFF = 0xFFFE0100 = // 32 bits are enough
0xFFFF * 0xFFFF + 0xFFFF = 0xFFFF0000 // 32 bits are enough
If all registers are signed, then 0xFFFF = -32767, but 0xFFFF * 0xFFFF would be the same as before (negative * negative = positive). Register C will make the result a little smaller than the previous result, but you would still require 32 bits in order to store it.
I am trying to implement bitstuffing for a project I am working on, namely a simple software AFSK modem. The simplified protocol looks something like this:
0111 1110 # burst sequence
0111 1110 # 16 times 0b0111_1110
...
0111 1110
...
... # 80 bit header (CRC, frame counter, etc.)
...
0111 1110 # header delimiter
...
... # data
...
0111 1110 # end-of-frame sequence
Now I need to find the reserved sequence 0111 1110 in the received data and therefore must ensure that neither the header nor the data contains six consecutive 1s. This can be done by bit stuffing, e.g. inserting a zero after every sequence of five 1s:
11111111
converts to
111110111
and
11111000
converts to
111110000
If I want to implement this efficiently I guess I should not use arrays of 1s and 0s, where I have to convert the data bytes to 1s and 0s, then populate an array etc. but bitfields of static size do not seem to fit either, because the length of the content is variable due to the bit stuffing.
Which data structure can I use to do bit stuffing more efficiently?
I just saw this question now and seeing that it is unanswered and not deleted I'll go ahead and answer. It might help others who see this question and also provide closure.
Bit stuffing: here the maximum contiguous sequence of 1's is 5. After 5 1's there should be a 0 appended after those 5 1's.
Here is the C program that does that:
#include <stdio.h>
typedef unsigned long long int ulli;
int main()
{
ulli buf = 0x0fffff01, // data to be stuffed
temp2= 1ull << ((sizeof(ulli)*8)-1), // mask to stuff data
temp3 = 0; // temporary
int count = 0; // continuous 1s indicator
while(temp2)
{
if((buf & temp2) && count <= 5) // enter the loop if the bit is `1` and if count <= 5
{
count++;
if(count == 5)
{
temp3 = buf & (~(temp2 - 1ull)); // make MS bits all 1s
temp3 <<= 1ull; // shift 1 bit to accomodeate the `0`
temp3 |= buf & ((temp2) - 1); // add back the LS bits or original producing stuffed data
buf = temp3;
count = 0; // reset count
printf("%llx\n",temp3); // debug only
}
}
else
{
count = 0; // this was what took 95% of my debug time. i had not put this else clause :-)
}
temp2 >>=1; // move on to next bit.
}
printf("ans = %llx",buf); // finally
}
The problem with this is that if there are more that 10 of 5 consecutive 1s then it might overflow. It's better to divide and then bitstuff and repeat.
Hi another silly simple question. I have noticed that in certain typedefs in Apple's frameworks use the symbols "<<" can anyone tell me what that means?:
enum {
UIViewAutoresizingNone = 0,
UIViewAutoresizingFlexibleLeftMargin = 1 << 0,
UIViewAutoresizingFlexibleWidth = 1 << 1,
UIViewAutoresizingFlexibleRightMargin = 1 << 2,
UIViewAutoresizingFlexibleTopMargin = 1 << 3,
UIViewAutoresizingFlexibleHeight = 1 << 4,
UIViewAutoresizingFlexibleBottomMargin = 1 << 5
};
typedef NSUInteger UIViewAutoresizing;
Edit: Alright so I now understand how and why you would use the left bit-shift, my next question is how would I test to see if the the value had a certain trait using and if/then statement or a switch/case method?
This is a way to create constants that would be easy to mix. For example you can have an API to order an ice cream and you can choose any of vanilla, chocolate and strawberry flavours. You could use booleans, but that’s a bit heavy:
- (void) iceCreamWithVanilla: (BOOL) v chocolate: (BOOL) ch strawerry: (BOOL) st;
A nice trick to solve this is using numbers, where you can mix the flavours using simple adding. Let’s say 1 for vanilla, 2 for chocolate and 4 for strawberry:
- (void) iceCreamWithFlavours: (NSUInteger) flavours;
Now if the number has its rightmost bit set, it’s got vanilla flavour in it, another bit stands for chocolate and the third bit from right is strawberry. For example vanilla + chocolate would be 1+2=3 decimal (011 in binary).
The bitshift operator x << y takes the left number (x) and shifts its bits y times. It’s a good tool to create numeric constants:
1 << 0 = 001 // vanilla
1 << 1 = 010 // chocolate
1 << 2 = 100 // strawberry
Voila! Now when you want a view with flexible left margin and flexible right margin, you can mix the flags using bitwise or: FlexibleRightMargin | FlexibleLeftMargin → 1<<2 | 1<<0 → 100 | 001 → 101. On the receiving end the method can mask the interesting bit using logical and:
// 101 & 100 = 100 or 4 decimal, which boolifies as YES
BOOL flexiRight = givenNumber & FlexibleRightMargin;
Hope that helps.
The << means that all bits in the expression on the left side are shifted left by the amount on the right side of the operator
so 1 << 1 means:
0001 becomes 0010 (those are binary numbers)
another example:
0001 0100 << 2 = 0101 0000
most of the time shift left is the same as multiply by 2.
exception:
when high bits are set and you shift them left (in a 16 bit integer 1000 0000 0000 0000 << 1) they will be discarded or wrapped around (i don't know how it is done in each language)
Its a bit shift.
In C-inspired languages, the left and
right shift operators are "<<" and
">>", respectively. The number of
places to shift is given as the second
argument to the shift operators.
Bit Shift!!!
For example
500 >> 4 = 31,
Original: 111110100
1st Shift:011111010
2nd Shift:001111101
3rd Shift:000111110
4th Shift:000011111 which equals 31.
Same as
500/16 = 31
500/2^4 = 31
Bitwise shift left. For more info see the Wikipedia article.