- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
Wow....
bitfield = 0;
Anyone? Bueller?
Admin
This is the stupidest thing I have ever seen.
Admin
What's even more hilarious is that the guy knows how to use bitwise operators and yet iterates through bit by bit instead of just bitfield & ~bitfield (which would still be a WTF of course).
Admin
WITFF?
Essentially, create a function that does this:
<FONT color=#000099>unsigned int</FONT> resetBits(<FONT color=#000099>unsigned int</FONT> bitfield)
{
<FONT color=#000099>return</FONT> 0;
}
Admin
No. bitfield ^ bitfield does the job in half the instructions :)
Admin
I don't know C++ well enough, what do the first line and the tilde (~) do?
Admin
this is the most f-ing ridiculous solution I have ever seen.
How can anyone that understands the bit operations not realize that 0 and 0000000000000000000000000000000 are the same thing?
a teacher in my cs200 class asked a similiar question on a test, most the class put i=0;
but there were a few kids sweating and writing away at a solution. This guy must of been one of those guys.
Admin
If you use a decent compiler, it will be optimized to the same instruction(s) for your platform.
Admin
Apart from the obvious WTFs, I also love the NUMBITS macro, and the re-initialization of index to 0. You know, just to be safe.
Admin
Very, very hard to believe this one is real.
It would be interesting to see how various optimizers handle this code.
Admin
NOT / flips the bit
Admin
that was in response to Manni
Admin
flip all of the bits of an integer (representing a bitfield) to zero
I had to read this several times, just to be sure I wasn't missing anything... The obvious "solution" seemed too simple to warrant writing any actual "code", let alone an entire function with macros and everything!
Admin
Cool yeah I figured you were replying to me. Then I'm completely retarded, I can't see how this is returning 0. Help me so I never make this mistake.
Admin
Remember:
int i=0 DOES NOT guarantee that all bits will be 0.
If this is "C", see: http://groups-beta.google.com/group/comp.lang.c/msg/fed3e094bd617097?dmode=source&hl=en
It discusses the two situtations in which 0 is NOT all bits 0
Admin
I don't know the language very well, but it looks like the function was supposed to take the number passed into it and flip every bit, not simply flip them all to 0. The WTFs I *am* capable of spotting are that he never uses the parameter he passed into it except for creating his output value, and the fact that he declared the index integer and initialized it to 0, when that could have been easily done in the declaration of the for loop.
If index keeps growing, what will GENBIT(index) return?
Admin
It does in fact zero out the integer.
For each bit in the integer, it first creates a bitmask like this:
00000000000000000000000000000001 (where the 1 is in the correct position for the current bit)
Then he negates it:
11111111111111111111111111111110
Then he ANDs it with the number, thus making the current bit 0.
Admin
This guy is retarded in both cases, with case 1 being flip all bits to zero and case 2 being flip all bits to the opposite value. In either case, it could have been done in a single line of code:
In the case of 0 not being all zeros, this is true only if you will be compiling for a processor that is capable of have a 0 with 1 bits for parity or padding. This probably did not apply in this case--for it was submitted to this site.
case 0:
return 0x00000000; //This will get rid of those wascally 1s.
case 1:
return bitfield ^ 0xFFFFFFFF;
^ is the bitwise XOR operator in C++, C, and C#.
Admin
my c/c++ is a little rusty, but
GENBIT is a macro that just does 1<<x , which shifts over to the x(index) bit
this guy then finds the opposite value of that bit and then AND s them ultimatley giving you a 0 in all cases
ie)
flag = 0000000
bitfield= 0100001
ANDed
= 0100000
then
flag = 0000010
bitfield= 0100000
ANDed
= 0100000
etc.
At a glance that looks like what it does, I'm sure sombody will correct me if I'm wrong.
Admin
Even so, i ^ i should be a faster way to all zeros.
And to the poster of the comment that i ^i is faster than i & ~i: This is not necessarily the case. The xor operation decomposes into seperate operations. Some architectures this is done at the hardware level, some through a psuedoinstruction. Remember:
A ^ B === ( ~A & B ) | ( A & ~B )
At the hardware level, doing A & ~A would be approximately 33-50% faster than the above, due to transistor latency and propagation delays.
Admin
Your bitwise logic is incorrect. 0 AND x = 0, regardless of x, so 0000000 AND 0100001 is 0000000.
Admin
Sadly, the first thing that came to my head was:
return bitfield & 0
Admin
Sweets I appreciate you taking the time to try to explain exactly what the various pieces are doing. Everyone else was too busy trying to figure out how to reduce the operation to a flawless solution considering buffering bits or whatever, and so that it takes less than 2 microseconds.
Admin
Another way to see if it's faster or not is to look at the number of clock cycles it takes to complete the instruction. Its likely the instruction just passes bits through the logic gates, which would only take a single pulse of the clock. I believe this is an optimized way of clearing registers in x86 assembly.. I may be wrong, but it seems like every high performace compiler, even Intel's does this when it needs to empty a register..
Of course, doing that to a variable in a memory location can be a different story, depending on if/how the compiler optimizes. & ~ works just as well, too... but, generally on any modern processor, it will be 2 instructions instead of a single instruction.
Admin
You're right. I typed it out kinda quickly and wasn't going for correctness since I knew someone would correct me.
Anyway, I try to avoid bitwise operations on Friday
Admin
You are wrong. i & ~i is not a single instruction :
1) negate i
2) And the negated i with i
By the way XOR is a single instruction.
Admin
But we can all agree that
unsigned long int i = 0;
will be 32 bits worth of zeros;
Admin
Hm. I must not have been clear: Let me rephrase:
"... AND NOT will be 2 instructions instead of XOR's single instruction"
I think what the post I was replying to was eluding to the fact that XOR may be more complex in microcode. I don't necessarily think this is so.
Admin
Not necessarily, it could be 48 bits of zeros with 16 bits worth of "padding" which could be either 0's or 1's.
Of course, I know of no compiler or archetecture that does this....
Admin
Working on an Athlon64 on Linux, I most definitely cannot agree.
unsigned long int i = 0;
On my machine, this is 64 bits worth of zeros.
The padding bits are irrelevant. They are not part of the value, and as such may not influence comparisons, may not be used by bitfields - they are a hardware-level detail and might as well not be there as far as the programmer is concerned.
Admin
If it's x86, everyone (or at least everyone doing assembly) knows that XOR is the fastest way to zero out a register. This is so common it's even done to set something to zero in unoptimized code.
Admin
andnot t0, t0, t0
Perfectly valid Alpha assembly. AND NOT can indeed be a single instruction.
Admin
That code would be horrible in anything time critical! He should really use Duff's Device to unroll that loop:
Admin
Thanks! To those that missed it, my original point is that xor is not necessarily the fastest way **on all architectures**. Even if it is the "simplest" from an assembler standpoint. Every way I've seen the operation designed in hardware, using either static or dynamic logic, xor is always slower than the "and not" approach. x86 is not all there is in the world, people.
Admin
Finally, a WTF I get, being a new programmer!
What a dumbass!
Admin
Advantages to this code:
Allows for scalability - If the INTEGER size changes from 32 bit to, say, 33 bit, a single define allows the new hardware to be supported.
Handles different types of zeros (Binary, decimal and hexadecimal - Might handle Octal, too, but I'm not too sure about that one.)
Actually works for unsigned AND signed integers though the code only calls out unsigned.
Renders DeMorgan's Theorem moot!
Admin
Today I did this:
showTheThingy |= true;
Not even drunk.
Admin
There's a cure for that...
Admin
unsigned int = QWORD? = byte[0000]-byte[0000]-byte[0000]-byte[0000]? ok not FFFF-FFFF-FFFF-FFFF but 0000-0000-0000-0000? I don't know I'm just like um macro? WTF? WTH I got paid....
Admin
An integer in C would never have an odd number of bits - it used to generally be 16 bits, now it is usually 32 bits - it is always a power of two multiple of the basic data element (char in C)
PS: how come the CAPTCHA validation never works the first time round ?
Admin
It's not necessarily the fastest way on very late-model x86 architectures. The instruction decoder/scheduler might decide that "xor eax,eax" is dependent upon the result of a previous instruction which modifies eax (obviously it's not - but they might use the same logic for "xor ebx, eax", which is obviously dependent on eax). "mov eax, 0", or any other immediate load, on the other hand is obviously not dependent on any previous value of eax, so even though it's a more complex instruction to decode, it could conceivably be faster.
Basically, it's never a good idea to say that "Foo is the fastest way to do Bar on x86", because there's so much wackiness going on in the architecture from generation to generation.
Admin
Or just ~bitfield, which is size-independent and thus 64-bit clean.
Admin
..except that on x86 machines (and probably others), shifting by 32 bits is a null operation. C/C++ may be able to catch it in a literal case, but otherwise I don't think it'll prevent you from doing something stupid.
Admin
At least genbit is a macro vs. a function. You've got to give him credit for that little stroke of efficiency.
Seriously though - you're making this stuff up right? I mean yesterday was the vbscript that generated html links and today we're circumventing simple assignment. This stuff can't be real...I hope...
Admin
Reminds me that in the good old days when every CPU cycle counted, the fastest way to zero a register was to XOR it with itself. It was both less cycles (2 or 3) and less bytes (1 byte) than assigning literal zero to it.
Admin
Sadly, it is real -- really real (as in, not from message boards and whatnot).
Ever watch the JERRY SPRINGER show? It's kinda like that with programming. I've contributed a good 6 or 7 posts from a single place I worked at for less than two years. Multiply that by the number of readers and you have TDWTF :-)
Admin
Wait a minute, there. I can certainly agree that if you are restricted to working at the gate level, XOR would be slower, but if you are working directly in, say, CMOS, could you not have something with cross-wired P vs. N gates? (I know that's not very clear, but I can't draw a picture here. I mean can you make an XOR directly in transistors that is smaller, simpler, and faster than if you did it using AND/OR primitives?)
Admin
the guy who wrote that was at one point training to be a police officer, nuff said...
and that genbit macro and most of those bitwise operations he copy pasted from someone else's code and hacked at it until it did what he "wanted"
Admin
I think the really fastest way to tell the compiler what this function really does is a preprocessor macro:
#define resetBits(x) 0
Or if you really want to explain what it does:
#defin resetBits(x) ((x) & 0)
And with a fool-proof comment:
#define resetBits(x) ((x) & 0) /* reset bits of x */
Admin
Uh, not in this case. First of all, the argument and result are unsigned, so sign bits are irrelevant. Second, padding would be irrelevant here too, since only the non-padded bits would be returned from the function. No, every caller of this function should just be replaced with an assignment of 0 (the compiler will do a nice job of optimizing this, BTW) and the function and the programmer should be discarded.