I have an array of type uint8_t storing 0's and 1's. When I do the negation on each element I get an array of -1's and -2's. How is this possible? How do I make it perform the way it's supposed to?
It's actually doing the right thing, but it's just being displayed improperly. Negative numbers are represented using two's complement. To convert a number to negative, you do: NOT(positive) + 1.
As an example, to convert 2 to a negative number:
+2 = 00000010
not(+2) = 11111101
not(+2) + 1 = 11111110
This means that -2 is represented by 11111110 in binary. Notice how this is actually the bit inverse of +1, which is 00000001. This explains why you're seeing what you are, but why isn't it showing you the positive like expected? This depends on how you're displaying it. You most likely used printf or a similar string formatter with %i rather than %u, so the compiler is casting it automatically for you. If you change your format, it should be fixed.
If you're just wanting to change between true and false, use ! instead of ~.
If I recall, the ~ operator flips all the bits. For a signed char integer, the above is correct. For example, for a signed char, 0=00000000, 1=00000001, -1=11111111, -2=11111110.
If you want values for "true" and "false", usually false is all-bit-zero (=0) and "true" is all-bits-1 (=-1). Then, ~true==false and ~false==true.
If you want to toggle between 0 and 1, you can use the xor operator ^ to toggle specific bits; in this case, you want to toggle the lowest bit, so use ^1. 0^1==1 and 1^1==0.
Related
c program to check odd or even without using modulus operator
We can check a number is even or odd without using modulus and division operator in c program
The another method is using shift operators
number >> 1) <<1==number then it is even number,can someone explaain this?
A right shift by x is essentially a truncating division by 2x.
A left shift by x is essentially a multiplication by 2x.
6 ⇒ 3 ⇒ 6
7 ⇒ 3 ⇒ 6
If this produces the original number, it's even.
An unsigned number is odd if its lowest (1) bit is 1. What this does is shift right by 1, and then right by one, effictively zeroing out this first bit. If that bit was already a 0 (i.e. the number is even), then the number doesn't change and the == passes. If it was a 1 then its now a zero and the equality check fails.
A better, more obvious implementation of this logic would be:
if((number & 0x1) == 0)
which checks directly whether the bit is a 0 (i.e. the number is even)
We can check a number is even or odd without using modulus and division operator in c program The another method is using shift operators number >> 1) <<1==number then it is even number
Do not use if(( number >> 1) <<1==number) as it risks implementation defined behavior when number < 0.
Only for the pedantic
This is likely incorrect on rare machines that use ones' complement int encoding.
Of course such beast are so rare these days and the next version of C, C2x, is expected to no longer support non-2's complement encoding.
Alternative
Instead code can use:
is_odd = number & 1LLU;
This will convert various possible integer types of number into unsigned long long and then perform a simple mask of the least significant bit (the one's place). Even with negatives values in any encoding will convert mathematically to an unsigned value with the same even-ness.
Modulus operator??
... using modulus and division operator ...
In C there is no operator defined as modulus. There is %, which results in the remainder.
See What's the difference between “mod” and “remainder”?.
Right-shifting by one shifts off the low bit, left-shifting back restores the value without that low bit.
All odd numbers end in a low bit of 1, which this removes, so the equality comparison only returns true for even numbers, where the removal and re-adding of the low 0 bit does not change the value.
I am writing an emulator in C and I want to make the constantValuable , which is 65530 (0xFFFA) be the two's complement variable of 5 however I cannot seem to get it quite right. Below is the example of the if statement where I would like this to be done.
if(opCodeType == 4)
{
if(registers[rsVariable] == registers[rtVariable])
{
int twosVariable = ~(constantVariable) + 1;
printf("%d", twosVariable);
pc = pc + (twosVariable*4);
}
}
I can't seem to understand why this does not work.
Indeed 2's complement is such that the complement to your number n (which algebraically is -n) is derived by reflecting the bit pattern of n then adding 1 to that number. Note that in a 2's complement scheme, -1 has all its bits set to 1.
The problem with reflecting the bit pattern using ~ is that it can cause unwanted type promotion which ruins the result.
One solution is to mask the the result of ~, another is to cast the result. Of course, on a 2's complement platform, you can write simply -n, taking care to ensure that n is not already the smallest possible negative.
I have 8 bit int zero = 0b00000000; and 8 bit int one = 0b00000001;
according to binary arithmetic rule,
0 - 1 = 1 (borrow 1 from next significant bit).
So if I have:
int s = zero - one;
s = -1;
-1 = 0b1111111;
where all those 1s are coming from? There are nothing to borrow since all bits are 0 in zero variable.
This is a great question and has to do with how computers represent integer values.
If you’re writing out a negative number in base ten, you just write out the regular number and then prefix it with a minus sign. But if you’re working inside a computer where everything needs to either be a zero or a one, you don’t have any minus signs. The question then comes up of how you then choose to represent negative values.
One popular way of doing this is to use signed two’s complement form. The way this works is that you write the number using ones and zeros, except that the meaning of those ones and zeros differs from “standard” binary in how they’re interpreted. Specifically, if you have a signed 8-bit number, the lower seven bits have their standard meaning as 20, 21, 22, etc. However, the meaning of the most significant bit is changed: instead of representing 27, it represents the value -27.
So let’s look at the number 0b11111111. This would be interpreted as
-27 + 26 + 25 + 24 + 23 + 22 + 21 + 20
= -128 + 64 + 32 + 16 + 8 + 4 + 2 + 1
= -1
which is why this collection of bits represents -1.
There’s another way to interpret what’s going on here. Given that our integer only has eight bits to work with, we know that there’s no way to represent all possible integers. If you pick any 257 integer values, given that there are only 256 possible bit patterns, there’s no way to uniquely represent all these numbers.
To address this, we could alternatively say that we’re going to have our integer values represent not the true value of the integer, but the value of that integer modulo 256. All of the values we’ll store will be between 0 and 255, inclusive.
In that case, what is 0 - 1? It’s -1, but if we take that value mod 256 and force it to be nonnegative, then we get back that -1 = 255 (mod 256). And how would you write 255 in binary? It’s 0b11111111.
There’s a ton of other cool stuff to learn here if you’re interested, so I’d recommend reading up on signed and unsigned two’s-complement numbers.
As some exercises: what would -4 look like in this format? How about -9?
These aren't the only ways you can represent numbers in a computer, but they're probably the most popular. Some older computers used the balanced ternary number system (notably the Setun machine). There's also the one's complement format, which isn't super popular these days.
Zero minus one must give some number such that if you add one to it, you get zero. The only number you can add one to and get zero is the one represented in binary as all 1's. So that's what you get.
So long as you use any valid form of arithmetic, you get the same results. If there are eight cars and someone takes away three cars, the value you get for how many case are left should be five, regardless of whether you do the math with binary, decimal, or any other kind of representation.
So any valid system of representation that supports the operations you are using with their normal meanings must produce the same result. When you take the representation for zero and perform the subtraction operation using the representation for one, you must get the representation such that when you add one to it, you get the representation for zero. Otherwise, the result is just wrong based on the definitions of addition, subtraction, zero, one, and so on.
I wrote a program to print out the bit pattern of a float number in C.
So I expected to receive a standard-IEEE-754 bit pattern i.e.:
1 sign bit | 8 EXP bits | 23 mantissa bits
when I got the output and put the result to an IEEE-754 converter the number was wrong. When I bit by bit reversed the order, the number was correct.
So why I'm asking is: I found a thread in which I learned that the pattern could be BYTE-WISE reversed, but nowhere I found it completely BIT-WISE reversed.
Can anyone claryfy on this, please?
Here's a Screenshot of the program, the output and the conversion result.
(As you can see I put the numbers into the converter in reversed order and the result looks fine to me.)
Endianness is not the issue here, since you're using a bit-shift operator on the value of the entire object.
You simply printed out the bits in the opposite order, there is nothing more than that.
You start printing least significant bits first, and the webpage starts with most significant bits. Both variants are correct.
One a side node, the way you're interpreting the float as an int is not correct and it causes undefined behavior. You should use an unsigned integer with its width equal or greater to the width of type float, and use memcpy.
I'm dealing with some C code that includes
return ~0;
What does that mean? It's pretty much impossible to google for...
~ is a bitwise not/complement, aka it changes all 0's to 1's and vice-versa. ~0 is a value with all bits set to 1.
The key to answering this class of question as you inspect the code is to recognize enough of the structure of the language to know what question to ask. For example, the return statement requires an expression, of a type compatible with the declared return type for the function itself.
Knowing that ~0 must be an expression, it is either a really funny way to write a number, or it is an operator you don't recognize applied to the constant zero. That latter hypothesis is easily checked, and googling for "C language operator" will quickly lead to dozens of tables of operators. Nearly any one of which will tell you that the ~ operator is a bitwise-not unary operator which inverts each individual bit of its operand. In this specific case, that converts the signed integer 0 to the integer represented with all its bits set.
On the majority of platforms you will encounter, that integer has the value -1.
The ~ (tilde) operator performs a bitwise complement on its single integer operand.
Complementing a number means to change all the 0 bits to 1 and all the 1s to 0s
Anyway, for search queries with special symbols like yours "return ~0;" you can use
http://symbolhound.com/
It is pretty useful for programmer.
There are two independent parts here: return and ~0.
return is a return statement. Read about it in your favorite C book.
~0 is an expression consisting of bitwise-complement operator ~ applied to integer constant 0. All bits in a zero value of type int are inverted (become 1) and the resultant int value (with all bits set to 1) is what the ~0 expression evaluates to. On a two's complement machine a signed integral value with such bit pattern (111...1) would represent -1.
Not zero or True.
The tilde does a bitwise compliment of the number 0, which returns back a value with all bits set to 1, with whatever size of the return value (so you'd get 0xFF for a char, etc.)