Hex Twos Complement Arithmetic - subtraction

I'm trying to do the following problem:
E8B2035D
-FB60528D
----------
In which, the integers represented are hex representations of 32-bit two's compliment binary numbers. What is the best approach to solve this problem, and detect overflow?

Subtraction becomes addition when you use two's complement. So I would take the complement of the second number, then add them:
As you know, the two's complement of a number starts out by turning every 1 into 0 and vice versa (handy rule of thumb: do 15 - number, so F -> 0, E -> 1, D -> 2, etc):
FB60528D --> 049FAD72
Then add one to the number (in this case, 2 + 1 = 3, and there is no carry):
049FAD73 -- the two's complement of FB60528D
Now we add the numbers, using conventional rules of addition:
E8B2035D
049FAD73 +
----------
D + 3 = 10 : write 0, carry 1
1 + 5 + 7 : write D, carry 0
3 + D = 10 : write 0, carry 1
1 + 0 + A : write B, carry 0
2 + F : write 1, carry 1
1 + B + 9 : write 5, carry 1
1 + 8 + 4 : write D, carry 0
E + 0 : write E
The final result (still in two's complement) is
ED51B0D0
You would detect overflow if the last calculation resulted in a carry (a number > F).

Related

Why Int8.max &+ Int8.max equals to "-2"?

Following Swift Standard Library documentation, &+ discards any bits that overflow the fixed width of the integer type. I just did not get why adding two maximum values, 8-bit signed integer can hold results in -2:
/// Two max Int8 values (127 each, 8-bit group)
let x6 = Int8.max
let x7 = Int8.max
/// Prints `1 1 1 1 1 1 1`
String(Int8.max, radix: 2)
/// Here we get `-2` in decimal system
let x8 = x6 &+ x7
/// Prints `-1 0`
String(x8, radix: 2)
If we break down the binary calculation we will get this:
1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1
-----------------------------
1 1 1 1 1 1 1 0
Which is -126, as the leftmost bit is a negative sign.
Why does Swift discards any bits except the rightmost two (1 and 0). Did I miss some overflow rules? I've read some pieces of knowledge in the web, but did not get closed to cracking this one.
Swift (and every other programming language I know) uses 2's complement to represent signed integers, rather than sign-and-magnitude as you seem to assume.
In the 2's complement representation, the leftmost 1 does not represent "a negative sign". You can think of it as representing -128, so the Int8 value of -2 would be represented as 1111 1110 (-128 + 64 + 32 + 16 + 8 + 4 + 2).
OTOH, -126 would be represented as 1000 0010 (-128 + 2).

How to read 19bits out of 3 bytes in Swift?

I have a Data object with 20 bytes that I'm getting from a BLE device.
This is an example when I po the data in the CBCharacteristic:
▿ 20 bytes
- count : 20
▿ pointer : 0x0000000282889ab0
- pointerValue : 10779925168
▿ bytes : 20 elements
- 0 : 16
- 1 : 0
- 2 : 0
- 3 : 21
- 4 : 0
- 5 : 0
- 6 : 20
- 7 : 3
- 8 : 87
- 9 : 154
- 10 : 3
- 11 : 88
- 12 : 204
- 13 : 20
- 14 : 255
- 15 : 197
- 16 : 7
- 17 : 159
- 18 : 56
- 19 : 122
Now I have instructions that tell me that on Byte 1,2,3 there is the signal that I'm looking for as 19 bits (0-524288)
So how can I get that signal value?
I would appreciate reading material on how to get this on my own if necessary. I don't have a proper CS background and I'm lost on how/where to even look for this.
Thank you
EDIT (in response to #Sweeper):
These are instructions for Byte 0
General state / configuration. Contains following bits:
7 (highest) – Error state, reads 0 normally and 1 if any error in hardware side
6 – button pressed (’1’ – button is pressed, ’0’ – button is not pressed)
5 – USB connected (’1’ – USB is connected, ’0’ – USB is not connected)
4 – Charging/charged (’1’ – Charging, ’0’ – not charging)
3 – Gain of channel A. 2 gains (0 is slower, 1 is higher)
2 – Gain of channel B. 2 gains (0 is slower, 1 is higher)
1 – Gain of channel C. 2 gains (0 is slower, 1 is higher)
0 – Gain of channel D. 2 gains (0 is slower, 1 is higher)
And by doing this I can get the expected data for the first byte:
guard let data = characteristic.value else { return }
guard data.count == 20 else { return }
let val = [UInt8](data)
let general:UInt8 = val[0]
let error = general >> 7 & 1
let buttonPressed = general >> 6 & 1
let usbConnected = general >> 5 & 1
let charging = general >> 4 & 1
let gainChannelA = general >> 3 & 1
let gainChannelB = general >> 2 & 1
let gainChannelC = general >> 1 & 1
let gainChannelD = general >> 0 & 1
Does this help in knowing the endianness of the protocol?
Since the data comes from multiple bytes, the answer depends on the endianness implied by the protocol. These 19 bits use two full bytes and three bits in a third byte.
If these three bytes are stored in unsigned 8-bit variables a, b, and c, the value would be either
Int(a) << 11 + Int(b) << 3 + Int(c) & 0x07
or
Int(c) << 11 + Int(b) << 3 + Int(a) & 0x07
values for a b and c would come either from bytes 1, 2, and 3 or bytes 3, 2, 1, depending on the order specified in the protocol.
Note: Expression x & 0x07 means "three lower bits", because 0x07 hex is 00000111 in binary.

Multiple formatted by 0/1 [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Find multiple of a number that can be written with 1s and 0s
Given the number n (2 <= n <= 1000), find the lowest nonzero multiple of which is written in base 10 with digits 0 and 1 only. Examples: 2 -> 10, 3 -> 111, 4 -> 100, 7 -> 1001, 11 -> 11, 9 -> 111 111 111.
I think, follow the remaining division of numbers consist of numbers n which is formatted 0/1.Thanks for your help!
{10/3= 3 remaining 1 -> and the finaly is 111 !!!
10/4= 4 ramining 2 -> and the finaly is 100 !!!
10/6= 1 ramainin 4 -> and the finaly is 1110 !!!
I don't understand is the logic}
The question is basically saying: Find the first non-zero multiple of n that consists of only 1s and 0s. And we're not talking binary (base 2) or remainders or anything fancy here. Here are some examples, in the format:
n => The first multiple of n with only 1s and 0s is x (n * y = x)
--------------------------------------------------------------------------
2 => (2 x 5 = 10)
3 => (3 x 37 = 111)
4 => (4 x 25 = 100)
7 => (7 x 143 = 1001)
11 => (11 x 1 = 11)
9 => (9 x 12,345,679 = 111,111,111)
You need to figure out an algorithm to make it work! You could use brute force:
for each n between 2 and 1000
y = 1
x = 0
do
x = n * y++
while (x is not 0 and string(x) is not all 0s and 1s)
print n => x
next n
I implemented this in C# to test it and it gave me the following output for n between 2 and 10:
2 => 10
3 => 111
4 => 100
5 => 10
6 => 1110
7 => 1001
8 => 1000
9 => 111111111
10 => 10
There are probably faster implementations, but this should give you an idea of where to start.
If you're asking for help interpreting the (homework) question, here's what I think it means: "For a given number, find out lowest multiple of it that contains only digits 1 or 0"
So, for example, if the number is 2:
Multiples of 2 = {2, 4, 6, 8, 10, 12, 14, .... }
|
|
this is your answer!
The non-bruteforce way to do this would be to iterate throught numbers that contain only 0 and 1 then figure out if the number is a multiple of the number in question. This approach will be substantially more efficient than iterating through the multiples of n and determining if it contains only 0 and 1.
An easy way to get a list of numbers that contain only 0 and 1 would be iterate throught the integers and for each value, interpret its binary representation as a decimal number.
Here's an online demo to get you started: http://jsfiddle.net/6j5De/4/
Since it's likely to be homework, I'll leave it up to you to translate that to your subject language.

What Is The Purpose of Negative Modulus Operator Results?

I was previously under the (naive) assumption that the modulus operator returned the remainder of division. I was apparently wrong, as -2 % 5 returns 3. I would have thought that 5 divides -2 zero times with -2 as the remainder.
Now I understand the mechanics of how this operation is performed, but my question is why? Could someone give me a link to something that explains why modulus and remainder are not synonymous, or an example of a situation where it would be useful?
The result is entirely correct. Modular arithmetic defines the following (I'll use "congruent" since I can't type the equal sign with three lines)
a congruent b mod c iff a-b is a multiple of c, i.e. x * c = (a-b) for some integer x.
E.g.
0 congruent 0 mod 5 (0 * 5 = 0-0)
1 congruent 1 mod 5 (0 * 5 = 1-1)
2 congruent 2 mod 5 (0 * 5 = 2-2)
3 congruent 3 mod 5 (0 * 5 = 3-3)
4 congruent 4 mod 5 (0 * 5 = 4-4)
5 congruent 0 mod 5 (1 * 5 = 5-0)
6 congruent 1 mod 5 (1 * 5 = 6-1)
...
The same can be extended to negative integers:
-1 congruent 4 mod 5 (-1 * 5 = -1-4)
-2 congruent 3 mod 5 (-1 * 5 = -2-3)
-3 congruent 2 mod 5 (-1 * 5 = -3-2)
-4 congruent 1 mod 5 (-1 * 5 = -4-1)
-5 congruent 5 mod 5 (-1 * 5 = -5-0)
-6 congruent 4 mod 5 (-2 * 5 = -6-4)
-7 congruent 3 mod 5 (-2 * 5 = -7-3)
...
As you can see, a lot of integers are congruent 3 mod 5:
..., -12, -7, -2, 3, 8, 13, ...
In mathematics, the set of these numbers is called the equivalence class induced by the equivalence relation "congruence". Our understanding of the remainder and the definition of the "mod" function are based on this equivalence class. The "remainder" or the result of a mod computation is a representative element of the equivalence class. By declaration we have chosen the smallest non-negative element (so -2 is not a valid candidate).
So when you read -2 mod 5 = x this translates to "Find the smallest non-negative x so that there exists an integer y with y * 5 = -2 - x", in concordance with the definition of congruence. The solution is y=1 and x = 3 as you can see by simply trying out other values for y.
a = n (mod m) is defined as a = n + m*t and it applies to negative numbers equally well. (Another to look at it is that a = n (mod m) means (a - n) is a multiple of m)
-2 = 3 (mod 5) because -2 = 3 - 5 (i.e. t = -1)
The convention is that the result of taking a modulo m is a number between 0 and m - 1 (inclusive)
The fundamental guarantee that you get is that
(a % b) + b * (a / b) == a
For signed values, there is no reason either sign should be the preferred outcome of a modulo or divide operation. Some languages fix one form, others leave it up to the implementation, so that the implementation can use whichever way the hardware happens to provide. The hardware instruction, in turn, may have been chosen to operate efficiently the hardware's representation of signed integers.
Generally, be very careful when using signed integers together with division, remainder and bit shift operations.
I guess it depends on whether you want your result rounded down or rounded towards 0:
2 / 5 = 0.4 = 5*0 + 2 works in both cases, whereas
-2 / 5 = -0.4 = 5*0 + -2 if you're rounding towards 0 (truncation),
-2 / 5 = -0.4 = 5*-1 + 3 if you're rounding down (floor).
Note that the result is always positive (for a positive divisor) in the second case and it would be useful, for example, when calculating an array index:
hashmapBuckets[getIntHash(obj) % hashmapBuckets.size].add(obj)
or normalizing an angle:
angle = angle % 360; //0-359
It is in fact the other case I'm having trouble finding practical examples for :)
--
Oh, and the Wikipedia page on the modulo operation has some nice graphs. Note that the remainder always has the same sign as the divisor for a floored division.
Think of modulo as an operator that wraps a line of length y (in terms of y % x) around a circle of x pegs. The remaining length of the line that doesn't fully wrap around x is the resultant.

Converting numbers between Number Bases

I'm working on a program that converts between number bases. For example Octal is 8, decimal is 10. Letters A to Z could be considered as base 26.
I want to convert a number like "A" into 0, Z into 25, "AA" into 27 and "BA" into 53.
Before I start coding I'm doing it on paper so I understand the process. To start out I'm trying to convert 533 to base 26.
What algorithm is best for doing this?
You need to assign a "digit" to each letter, like:
A = 0 N = 13
B = 1 O = 14
C = 2 P = 15
D = 3 Q = 16
E = 4 R = 17
F = 5 S = 18
G = 6 T = 19
H = 7 U = 20
I = 8 V = 21
J = 9 W = 22
K = 10 X = 23
L = 11 Y = 24
M = 12 Z = 25
Then, your {20,13} becomes UN.
Converting back is UN -> {20,13} -> (20 * 26 + 13) -> 52.
By way of further example, let's try the number 10163, just plucked out of the air at random.
Divide that by 26 until you get a number less than 26 (i.e., twice), and you get 15 with a fractional part of 0.03402366.
Multiply that by 26 and you get 0 with a fractional part of 0.88461516.
Multiply that by 26 and you get 23 (actually 22.99999416 on my calculator but, since the initial division was only two steps, we stop here - the very slight inaccuracy is due to the fact that the floating point numbers are being rounded).
So the "digits" are {15,0,23} which is the "number" PAX. Wow, what a coincidence?
To convert PAX back into decimal, its
P * 262 + A * 261 + X * 260
or
(15 * 676) + (0 * 26) + 23
= 10140 + 0 + 23
= 10163
Let's take a step back for a second, and look at decimal.
What does a number like "147" mean? Or rather, what do the characters '1', '4' and '7', when arranged like that, indicate?
There are ten digits in decimal, and after that, we add another digit to the left of the first, and so on as our number increases. So after "9" = 9*1, we get "10" = 1*10 + 0*1. So "147" is 1*10^2 + 4*10 + 7*1 = 147. Similarly, we can go backwards - 147/10^2 = 1, which maps to the character '1'. (147 % 10^2) / 10 = 4, which maps to the character '4'. And 147 % 10 = 7, which maps to the character '7'.
This works works for any base N - if we get the number 0, that maps to the first character in our set. The number 1 maps to the second character, and so on until the number N-1 maps to the last character in our set of digits.
You convert 20 and 13 to the symbols that represent 20 and 13 in your base 26 notation. It sounds like you are using the letters of the alphabet so, that would be UN (where A is 0 and Z is 25).
What language are you writing this in? If you're doing this in Perl you can use the CPAN module Math::Fleximal that I wrote many years ago while I was bored. If you're using a language with infinite precision integers, then life becomes much easier. All you have to do is take characters, convert them into an array of integers, then do the calculation to turn that into a number.