|
|
|
| Non-WTF Job: Python Developers Wanted at SocialServe (Charlotte, NC) |
| « Prev | Page 1 | Page 2 | Next » |
|
Wow....
bitfield = 0; Anyone? Bueller? |
|
This is the stupidest thing I have ever seen.
|
|
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). |
|
WITFF?
Essentially, create a function that does this:
|
No. bitfield ^ bitfield does the job in half the instructions :) |
|
I don't know C++ well enough, what do the first line and the tilde (~) do?
|
|
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. |
Re: Flipping Out Over Nothin'
2005-05-13 13:33
•
by
Robin Lavallée
|
|
If you use a decent compiler, it will be optimized to the same instruction(s) for your platform.
|
|
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.
|
|
Very, very hard to believe this one is real.
It would be interesting to see how various optimizers handle this code. |
|
NOT / flips the bit
|
that was in response to Manni |
|
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!
|
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. |
|
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 |
|
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? |
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. |
Re: Flipping Out Over Nothin'
2005-05-13 14:02
•
by
Brent Railey
|
|
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#. |
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. |
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. |
Your bitwise logic is incorrect. 0 AND x = 0, regardless of x, so 0000000 AND 0100001 is 0000000. |
|
Sadly, the first thing that came to my head was:
return bitfield & 0 |
|
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. |
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.
|
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 |
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.
|
Re: Flipping Out Over Nothin'
2005-05-13 15:14
•
by
Ifeanyi Echeruo
|
|
But we can all agree that unsigned long int i = 0; will be 32 bits worth of zeros; |
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. |
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.... |
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. |
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. |
andnot t0, t0, t0 Perfectly valid Alpha assembly. AND NOT can indeed be a single instruction. |
|
That code would be horrible in anything time critical! He should really use Duff's Device to unroll that loop:
unsigned int resetBits(unsigned int bitfield) {
unsigned int n=(NUMBITS+7)/8; unsigned int index=0; unsigned int flag; switch (index % 8) case 0: do{ flag=GENBIT(index++);flag=~flag;bitfield=bitfield&flag;
case 7: flag=GENBIT(index++);flag=~flag;bitfield=bitfield&flag; case 6: flag=GENBIT(index++);flag=~flag;bitfield=bitfield&flag; case 5: flag=GENBIT(index++);flag=~flag;bitfield=bitfield&flag; case 4: flag=GENBIT(index++);flag=~flag;bitfield=bitfield&flag; case 3: flag=GENBIT(index++);flag=~flag;bitfield=bitfield&flag; case 2: flag=GENBIT(index++);flag=~flag;bitfield=bitfield&flag; case 1: flag=GENBIT(index++);flag=~flag;bitfield=bitfield&flag; } while (--n>0); } return bitfield; } |
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. |
|
Finally, a WTF I get, being a new programmer!
What a dumbass! |
|
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! |
|
Today I did this: showTheThingy |= true; Not even drunk. |
There's a cure for that... |
Re: Flipping Out Over Nothin'
2005-05-13 17:03
•
by
MR. IDUNNOCNOMO
|
|
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....
|
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 ? |
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. |
Or just ~bitfield, which is size-independent and thus 64-bit clean. |
..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. |
|
At least genbit is a macro vs. a function. You've got
|
|
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.
|
Re: Flipping Out Over Nothin'
2005-05-13 21:15
•
by
Alex Papadimoulis
|
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 :-) |
|
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?) |
|
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" |
|
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 */ |
|
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. |
| « Prev | Page 1 | Page 2 | Next » |