473,387 Members | 1,834 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

More bit shifting issues


I seem to be having yet more wierd issue with bit shifting. It seems
the following code doesnt do anything under gcc (ie it returns -1 as
both results). Anyone know why? Is it another language definition or
CPU issue?

main()
{
printf("%d\n",(int)0xFFFFFFFF >1);
printf("%d\n",(int)-1 >1);
}

B2003
Apr 1 '08 #1
12 2217
Boltar <bo********@yahoo.co.ukwrites:
I seem to be having yet more wierd issue with bit shifting. It seems
the following code doesnt do anything under gcc (ie it returns -1 as
both results). Anyone know why? Is it another language definition or
CPU issue?

main()
{
printf("%d\n",(int)0xFFFFFFFF >1);
printf("%d\n",(int)-1 >1);
}

B2003
Try using unsigned values and report back ...
Apr 1 '08 #2
Boltar <bo********@yahoo.co.ukwrote:
printf("%d\n",(int)0xFFFFFFFF >1);
printf("%d\n",(int)-1 >1);
Right-shifting a negative value results in an implementation-defined
value. As a first guess, your implementation does an arithmetic right
shift where you expected a logical one. Both results are allowed.

Richard
Apr 1 '08 #3
Boltar wrote:
>
I seem to be having yet more wierd issue with bit shifting. It seems
the following code doesnt do anything under gcc (ie it returns -1 as
both results). Anyone know why? Is it another language definition or
CPU issue?

main()
{
printf("%d\n",(int)0xFFFFFFFF >1);
printf("%d\n",(int)-1 >1);
}
Shift-right of negative values is implementation-defined; you're likely
to get one of arithmetic right shift or logical right shift. (Some machines
have/had only one of these and would have to synthesise the other, which
would be Woefully Inefficient.)

It's wise to restrict ones bitwise operations to unsigned types, since
these can't have tricksy sign bits to cut you with their nasty sharp
edges.

--
"The whole apparatus had the look of having been put /Jack of Eagles/
together with the most frantic haste a fanatically
careful technician could muster."

Hewlett-Packard Limited registered no:
registered office: Cain Road, Bracknell, Berks RG12 1HN 690597 England

Apr 1 '08 #4
Boltar wrote:
I seem to be having yet more wierd issue with bit shifting. It seems
the following code doesnt do anything under gcc (ie it returns -1 as
both results).
It does something, namely to retain the signedness of your negative
values. It didn't have to. It could have shifted in zeros instead of
replicating the sign bit.
Anyone know why? Is it another language definition or
CPU issue?
It is a mistake on your part. See the code below.
main()
{
printf("%d\n",(int)0xFFFFFFFF >1);
printf("%d\n",(int)-1 >1);
}

#include <stdio.h /* mha: needed for the variadic
function printf */

int /* mha: main returns an int, say so */ main(void)
{
printf("right shifting a negative value has no portably\n"
"defined meaning, so the output of the next two\n"
"printf statements is up for grabs:\n");
printf(" ((int)0xFFFFFFFF >1) = %d\n", (int) 0xFFFFFFFF >1);
printf(" ((int)-1 >) = %d\n\n", (int) -1 >1);
printf("Note the difference in the following:\n");
printf(" (0xFFFFFFFF >1) = %u\n", 0xFFFFFFFF >1);
printf(" (int)(0xFFFFFFFF >1) = %d\n", (int) (0xFFFFFFFF >1));
return 0; /* mha: even if you can get away
without it, it is poor programming
practice not to return a value from
a function returning a value */
}

right shifting a negative value has no portably
defined meaning, so the output of the next two
printf statements is up for grabs:
((int)0xFFFFFFFF >1) = -1
((int)-1 >) = -1

Note the difference in the following:
(0xFFFFFFFF >1) = 2147483647
(int)(0xFFFFFFFF >1) = 2147483647
B2003
Apr 1 '08 #5
On Apr 1, 4:43 pm, "Bartc" <b...@freeuk.comwrote:
Right-shifting used to be an efficient way of dividing integer values by
powers of two.
But not any longer , any modern CPU has a div or mul type instruction.
>
The sign propagation is necessary to make it work with twos-complement
negative numbers.
So why don't the same rules apply to the &, | and ^ operators then?
For example why doesn't (int)-1 ^ 0xFFFFFFFF still give -1 instead of
zero?

B2003

Apr 1 '08 #6
Boltar <bo********@yahoo.co.ukwrites:
On Apr 1, 4:43 pm, "Bartc" <b...@freeuk.comwrote:
>Right-shifting used to be an efficient way of dividing integer values by
powers of two.

But not any longer , any modern CPU has a div or mul type instruction.
>>
The sign propagation is necessary to make it work with twos-complement
negative numbers.

So why don't the same rules apply to the &, | and ^ operators then?
For example why doesn't (int)-1 ^ 0xFFFFFFFF still give -1 instead of
zero?

B2003
Because its a bitwise operator and not a word operator. There is no
notion of "sign" with single bits being or'd, and'ed or xor'ed.

Apr 1 '08 #7
Boltar <bo********@yahoo.co.ukwrites:
On Apr 1, 4:43 pm, "Bartc" <b...@freeuk.comwrote:
>Right-shifting used to be an efficient way of dividing integer values by
powers of two.

But not any longer , any modern CPU has a div or mul type instruction.
Yes, but the div or mul instruction might still be slower than an
equivalent shift. More to the point, modern compilers are capable of
generating a shift instruction for multiplication or division by a
power of 2, *if* it makes the code faster and *if* it can prove that
the result is equivalent.

--
Keith Thompson (The_Other_Keith) <ks***@mib.org>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Apr 1 '08 #8
Boltar wrote:
On Apr 1, 4:43 pm, "Bartc" <b...@freeuk.comwrote:
>Right-shifting used to be an efficient way of dividing integer values by
powers of two.

But not any longer , any modern CPU has a div or mul type instruction.
Not in the embedded world. The processor I work with most frequently has
only optional support for mul and div.
Apr 1 '08 #9
Boltar wrote:
>
I seem to be having yet more wierd issue with bit shifting. It
seems the following code doesnt do anything under gcc (ie it
returns -1 as both results). Anyone know why? Is it another
language definition or CPU issue?

main() {
printf("%d\n",(int)0xFFFFFFFF >1);
printf("%d\n",(int)-1 >1);
}
I suspect this covers it:

6.5 Expressions

.... snip ...

[#4] Some operators (the unary operator ~, and the binary
operators <<, >>, &, ^, and |, collectively described as
bitwise operators) are required to have operands that have
integer type. These operators return values that depend on
the internal representations of integers, and have
implementation-defined and undefined aspects for signed
types.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.

--
Posted via a free Usenet account from http://www.teranews.com

Apr 1 '08 #10
On Apr 1, 11:08*am, Boltar <boltar2...@yahoo.co.ukwrote:
On Apr 1, 4:43 pm, "Bartc" <b...@freeuk.comwrote:
Right-shifting used to be an efficient way of dividing integer values by
powers of two.

But not any longer , any modern CPU has a div or mul type instruction.

Not at all. IPF, and many RISCs, for example, do not have an integer
divide (or often an FP one either). They often support a divide
approximation instruction, which you then need to follow with a few
iterations of Newton-Raphson to actually generate a quotient.

In any event, left shifts are typically a fair bit faster than
multiplies (often several times), although there are CPUs with
exceptional fast multiplies and exceptionally slow shifters where
that's not true, and right shifts are invariably *much* faster than
actual divisions (often 20-50 times).
Apr 1 '08 #11
On Apr 1, 11:58 pm, "robertwess...@yahoo.com"
<robertwess...@yahoo.comwrote:
In any event, left shifts are typically a fair bit faster than
multiplies (often several times), although there are CPUs with
exceptional fast multiplies and exceptionally slow shifters where
that's not true, and right shifts are invariably *much* faster than
actual divisions (often 20-50 times).
Well that begs the question of why the cpu integer div instruction
doesn't simply check the divisors least significant bit to see if its
set to zero (even) and if it is then use bit shifting to get the
result. Same for multiply.

B2003

Apr 2 '08 #12

"Boltar" <bo********@yahoo.co.ukwrote in message
news:86**********************************@s13g2000 prd.googlegroups.com...
On Apr 1, 11:58 pm, "robertwess...@yahoo.com"
<robertwess...@yahoo.comwrote:
>In any event, left shifts are typically a fair bit faster than
multiplies (often several times), although there are CPUs with
exceptional fast multiplies and exceptionally slow shifters where
that's not true, and right shifts are invariably *much* faster than
actual divisions (often 20-50 times).

Well that begs the question of why the cpu integer div instruction
doesn't simply check the divisors least significant bit to see if its
set to zero (even) and if it is then use bit shifting to get the
result. Same for multiply.
Probably because it's a *lot* easier to have separate instructions for
shift, which are essential anyway. And it would have to check there is only
one bit set.

Anyway most cpus must have a shift-right-logical which does exactly what you
want. It's up to your C implementation whether that is invoked by
right-shifting an unsigned value.

--
Bart
Apr 2 '08 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: David Stockwell | last post by:
Hi, My background is c/c++ and java. I'm learning python at this point. My question is does python share java's peculiar mode of bit shifting, or does python adhere closer to c's bit shifting?...
9
by: GGG | last post by:
Noticed something odd in the way bit shifting was working today. As far as I have ever heard, shifting will shift in zeros(signed ints aside) However I foudn something odd when I am shifting...
8
by: Nick Patavalis | last post by:
Ok, what is this supposed to print: #include <stdio.h> #include <stdint.h> int main (void) { uint32_t r, s;
5
by: James Dean | last post by:
I am recoding a project in C#.....i just wanted to know if these are equivalent and give the same result.... old C++ code for ( long loop = 0; loop < ( longWidth_bytes - 1); loop++) { *lpbLine...
2
by: salsipius | last post by:
Can someone please help me clarify the below code. I think the shifting has to do with converting datatypes and/or loss of data but am not really clear on the details, could you help shed some...
10
by: krunalb | last post by:
Hi, I am trying to shift unsigned long long value by 64 bits and this is what i get #include <stdio.h> int main() { unsigned short shiftby= 64;
20
by: Charles Sullivan | last post by:
I understand different processor hardware may store the bits in a byte in different order. Does it make a difference in C insofar as bit-shifting unsigned char variables is concerned? E.g, if I...
1
tifoso
by: tifoso | last post by:
I searched here and only found somebody with a round-robin arraylist issue here but what they suggest I tried already and it doesn't work for me I hope somebody can shed some light Scenario: I'm...
2
by: jimxoch | last post by:
Dear list, I have recently implemented a generic sequence searching template function, named single_pass_search, which is more generic than std::search and has better worst case complexity at...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.