Why can't I use ~0 to initialize signed char? [closed] - c

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
I wrote like this:
#include <stdio.h>
#include <limits.h>
main()
{
signed char i = ~0;
printf("%zu\n", i);
return 0;
}
But the result is 4294967295 instead of -1. Why does this happen?

When you use a signed char value in an expression, it is automatically converted to int. Then, when you print a signed int using a format specifier %zu, which is for formatting an unsigned size_t, you get erroneous results because of the mismatch.
To print a signed char correctly, using %hhd.
Additionally, you should understand that while a signed char value of −1 might be represented with the eight bits 11111111 (in eight-bit two’s complement), when it is converted to int, the result is the 32 bits 11111111111111111111111111111111 (which represents −1 using 32-bit two’s complement). When those bits are interpreted as a 32-bit unsigned integer, the result is 4294967295. That explains why “4294967295” may be printed rather than the “255” that would result from interpreting the eight-bit 11111111 as an unsigned integer.

you are printing i value using %zu. In unisgned format -1=2^32-1 which is equals to
4294967295. Compiler uses the formula 2^(sizeoftype in bits)-n to convert signed values to unsigned.

Related

Can anyone explaing how this answer is calculated? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
#include<stdio.h>
int main()
{
printf("%x", -1<<1);
getchar();
return 0;
}
Output:
Output is dependent on the compiler. For 32 bit compiler it would be fffffffe and for 16 bit it would be fffe.
This is from geek for geeks
-1 is a signed integer. A left shift on a signed integer with a negative value has undefined behavior according to the formal definition of the C language. This is part of the general rule that signed operations have undefined behavior when they overflow. the sign bit is set, and it must shift, but there's no room for it to go anywhere, so it overflows.
In practice, almost all platforms use two's complement representation for signed integers, and a left shift on a signed integer is treated as if the memory contained an unsigned integer. However, beware that compilers sometimes take advantage of the fact that this is undefined behavior to optimize in surprising ways.
-1 is all-bits-one, so a left shift drops the topmost bit and adds a 0 bit to the bottom. The result is 111…1110 in binary. If unsigned int is a 16-bit type, that's fffe in hexadecimal. If unsigned int is a 32-bit type, that's fffffffe. When that memory is read as a signed int, the value is -2 either way.
The %x specified requires an unsigned int as an argument. Passing an the signed version of the type is ok: it is converted to the unsigned value. The result of the conversion is 2^N - 2 where N is the number of bits in an unsigned int: as above, that's 0xfffe if N=16, 0xfffffffe if N=32.
It seems to me this answer is is just your 32-bit compiler casting (implicitly) -1 as long int for a signed integer, while the 16-bit compiler casts 1 to a "good old" int 16 bit integer.
Bad answer. A much better answer is given above by Gilles 'SO- stop being evil'. I am just editing this so it is not absolute non-sense.
As commented above, -1 is a signed integer, and left shifting (see here) a signed integer that is negative causes an undefined behavior because the sign bit has nowhere to go. In all the systems I have worked, that behavior is an overflow.
The reason why the results are different between 16-bit and 32-bit compilers might well just be the fact that 16-bit compilers use 16-bit integers, hence the 16 bit result fffe. I attached some code for you to try it out it find it would be useful.
Attached dirty test.
/* dirty_test.c
* This program left bit-shifts a signed integer and
* prints the byte content of the result to stdout.
*
* On *nix like systems, compile with
*
* cc dirty_test.c -o dirty_test.x
*/
#include <stdio.h>
int main(void)
{
int a;
// assigning a negative value causes the bit shift
// to produce an overflow.
a = -1;
printf("bytes before shift: %08x\n", a);
printf("bytes after shift: %08x\n", a << 1);
return 0;
}

need help regarding the output of the following code with explanation if possible [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
char c = 250;
c += 8;
What value does c have after the above statements are executed? (Give your answer as a decimal integer.)
i have tried the value 258,3.
tip : write out addition in binary.
The type char can be signed or unsigned - that depends on the implementation. Assuming 8-bit char the range of values that can be held are
Signed: -128 to 127
Unsigned: 0 to 255
The code starts with
char c = 250;
which is out of the permissible range of a signed char and what happens when you assign that value to a signed char is undefined. So lets assume that the char is unsigned and now
char c = 250;
is a valid assignment. So let's do the addition in binary as you were advised
Binary Decimal
11111010 250
00001000 8
-------- ---
100000010 ???
The sum overflows 8 bits, and with unsigned values, it is truncated to 8 bits (modulo 256).
00000010 2
So the result is either 2 (unsigned) or undefined (signed).
For an unsigned char you have a minimum value of 0 and a maximum value of 255.
Therefore if you add 250 to 8 you get 2.
This happens because when you have a value of 255 all the bits in that byte are 1. Incrementing the least significant bit will overflow all the way "to the end" and you are left with all bits at 0.
If you need a better understanding of this I recommend these:
https://en.wikipedia.org/wiki/Integer_overflow
https://en.wikipedia.org/wiki/Binary_number

Why does -0x80000000 + -0x80000000 == 0? [duplicate]

This question already has answers here:
Integer overflow concept
(2 answers)
Integer overflow and undefined behavior
(4 answers)
Closed 6 years ago.
While reading a book about programmign tricks I saw that -0x80000000 + -0x80000000 = 0. This didn't make sense to me so I wrote a quick C program below to test and indeed the answer is 0:
#include <stdio.h>
int main()
{
int x = -0x80000000;
int y = -0x80000000;
int z = x + y;
printf("Z is: %d", z);
return 0;
}
Could anyone shed any light as to why? I saw something about an overflow, but I can't see how an overflow causes 0 rather than an exception or other error. I get no warning or anything.
What's happening here is signed integer overflow, which is undefined behavior because the exact representation of signed integers is not defined.
In practice however, most machine use 2's complement representation for signed integers, and this particular program exploits that.
0x80000000 is an unsigned integer constant. The - negates it, changing the expression to signed. Assuming int is 32-bit on your system, this value still fits. In fact, it is the smallest value a signed 32-bit int can hold, and the hexadecimal representation of this number happens to be 0x80000000.
When adding numbers in 2's complement representation, it has the feature that you don't need to worry about the sign. They are added exactly the same way as unsigned numbers.
So when we add x and y, we get this:
0x80000000
+ 0x80000000
-------------
0x100000000
Because an int on your system is 32-bit, only the lowest 32 bits are kept. And the value of those bits is 0.
Again note that this is actually undefined behavior. It works because your machine uses 2's complement representation for signed integers and int is 32-bit. This is common for most machines / compilers, but not all.
What you're seeing is a lot of implementation defined behavior, very likely triggering undefined behavior at runtime. More than that is not possible to know without details about your and book writers architecture.
The result isn't meaningful without additional information. If you want a definite answer, consult the type ranges for your architecture and make sure the results of assignments and arithmetic fit into their respective types.

What happens when I apply the unary "-" operator to an unsigned integer? [duplicate]

This question already has answers here:
Assigning negative numbers to an unsigned int?
(14 answers)
Closed 6 years ago.
This should be a pretty simple question but I can't seem to find the answer in my textbook and can't find the right keywords to find it online.
What does it mean when you have a negative sign in front of an unsigned int?
Specifically, if x is an unsigned int equal to 1, what is the bit value of -x?
Per the C standard, arithmetic for unsigned integers is performed modulo 2bit width. So, for a 32-bit integer, the negation will be taken mod 232 = 4294967296.
For a 32-bit number, then, the value you'll get if you negate a number n is going to be 0-n = 4294967296-n. In your specific case, assuming unsigned int is 32 bits wide, you'd get 4294967296-1 = 4294967295 = 0xffffffff (the number with all bits set).
The relevant text in the C standard is in §6.2.5/9:
a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type
It will overflow in the negative direction, i.e. if your int is 16 bits x will be 65535. The bit value will be 1111111111111111 (16 ones)
If int is 32 bits, x will be 4294967295
when you apply the "-", the Two's complement of the integer is stored in variable. see here for details

unsigned int T = 0xFFFFFFFF equals to -1 in C?? it should not work as 2 compliment right after unsigned? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
unsigned int is the same as uint32_t? which is 32 bits of unsigned integers and not 2 compliment right?
uint32_t y = 0xFFFFFFFF; // gives -1 i dont get why is it negative?
uint8_t x = 0b11111111; // gives 255 i understand this
The bit pattern you are showing represents -1 for a signed integer, and the maximum value if it is representing an unsigned integer.
When you say it "gives -1", you should look at how you check that. If, for example, you print it with printf, you should make sure to use an unsigned format specifier.
uint32_t y = 0xFFFFFFFF; // gives -1 i dont get why is it negative?
The reason why it is negative is, because, by definition, any number where the highes sigfnificant bit is set, is to be interpreted as negative, when a signed type is used. In your case the value would be normally not considered to be negative, as uint is considered unsigned.
Consequently this means that for example:
0xFFFF is -1 when considered as a 16bit integer, but the same value is not negative when using a 32 bit integer.
The compiler is extending the signedness if the appropriate conversions are used. So the above value, would still become -1 if it is appropriately promoted to a 32bit int.

Categories

Resources