Hi,
Gives me a value of -32768. Code is written on 16 bit machine so unsigned int is 16bit and long unsigned bit is 32bit. How/why the value is negative?Code:long unsigned int ShiftedBit = 0; ShiftedBit = 1 << 15; printf("%ld", ShiftedBit);
Hi,
Gives me a value of -32768. Code is written on 16 bit machine so unsigned int is 16bit and long unsigned bit is 32bit. How/why the value is negative?Code:long unsigned int ShiftedBit = 0; ShiftedBit = 1 << 15; printf("%ld", ShiftedBit);
Because 1 and 15 are not long, so 1 << 15 is a 16-bit integer, which is then converted to long. Make it 1L << 15 and it will work like you expect [or 1L << 15L].
Of course, if you want to print an unsigned long, you should use %lu, not %ld. But you would get a huge number without the above changes to make the 1 and 15 long.
--
Mats
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.
Works now. Legend
I've found that 1 << 31 gives 'long' (-2147483648) instead of 'unsigned long'. Is that correct?
The result of unsigned or signed results are the same binary values - the only difference is how the value is interpreted by the display functions [and in comparisons]. In this case, did you actually notice my comment on using %lu rather than %ld when printing unsigned numbers? I think you are still using %ld, rather than %lu.
--
Mats
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.
so what's the real value of ShiftedBit?The result of unsigned or signed results are the same binary values - the only difference is how the value is interpreted by the display functions [and in comparisons]
Bit representation is:
So if I compare this thenCode:0x00008000 => 0000 0000 0000 0000 1000 0000 0000 0000Questions:Code:unsigned long int OtherBit = 1; unsigned long int ShiftedBit = 0; ShiftedBit = 1 << 15; if (ShiftedBit > OtherBit) putchar('T'); else putchar('F');
1.In this instance OtherBit is greater than ShiftedBit, as ShiftedBit represents int value of -32768?
2.Is the ShiftedBit implicitly casted to int?
My compiler doesn't support %ul
That's wrong - like the next question, I'd like to know what compiler that is, since it sounds like the compiler is actually comparing signed when it should compare unsigned. [
%lu, you mean? What compiler is that? I'm not aware of ANY (as in, Turbo C++ that is 15+ years old supports it, as did the Compilers I used on Atari ST around 20 years ago) compiler that doesn't, but there's a first for everything.2.Is the ShiftedBit implicitly casted to int?
My compiler doesn't support %ul
I recreated your test-case on my machine, using a short to temporarily hold the 1 << 15 value, and it creates a value that is 4 billion, which is greater than otherbit ("T" is output).
--
Mats
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.
Compiler is IAR for Embedded systems.
From the manual:
I use -e_small_write=_formatted_write (medium doesnt work either).Code:The printf and sprintf functions use a common formatter called _formatted_write. The ANSI standard version of _formatted_write is very large, and provides facilities not required in many applications. To reduce the memory consumption the following two alternative smaller versions are also provided in the standard C library: -e_small_write -e_medium_write
Yes, I tried %lu - my 'typo'
But, I've checked an assembly file (generated by the copiler if required), and look what I've found:It looks like the compiler has precalculated values for 'constant' shifts and puts a value into register instead of making shift (wonder if that's for speed as this would take less cycles than shifting).Code:unsigned long int BShift; --C-- BShift = 1 << 15; BShift = 1L << 15; --asm-- mov.l #-32768,er6 mov.l #32768,er0
Sure, I expect the compiler to resolve constant expressions like that [for speed - since there is no point in calculating a value if it is calculated from constants].
And yes, of course, if you use an embedded compiler that supplies a non-ANSI library, then you can expect to have non-standard behaviour.
I still think it's a bug in the compiler that it compares two unsigned long incorrectly, whatever the origin of the values. I suggest you contact IAR about that.
--
Mats
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.