Thread: Swap Byte

  1. #16
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Originally posted by Sebastiani
    Quzahs solution completes the task in less than a dozen operations - all of them assignment, none are comparisons either. That is what makes this solution superior. You have comparisons for loop bounds, lots of arithametic and so forth, which make for a more intensive program and hence, longer code segments, more register accesses, long math, etc.


    Just for the record, I did *not* make any posts to this thread! Some strange bug in the board caused the above posts to appear with my name on it.

    Thanks to Kermi3 for fixing that.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  2. #17
    Registered User pinko_liberal's Avatar
    Join Date
    Oct 2001
    Posts
    284

    Question

    6.2.6.1.7 When a value is stored in a member of an object of union type, the bytes of the object representation that do not correspond to that member but do correspond to other members take unspecified values, but the value of the union object shall not thereby become a trap representation
    I might be wrong but I feel the above means that if my union has (say) two members and I assign a value to one of the members the values of the other members takes unspecified values, so IMHO it rules out assigning a value to one member and assuming that other member's value have changed to particular value ( like assuming in union Quzah defined that the bit field has taken the values of the bit pattern that define the value of char member of the union when the char member is assigned a value). IMHO assigning a value to one member of union and then expecting another member of the union to take a specific value is not safe.
    The one who says it cannot be done should never interrupt the one who is doing it.

  3. #18
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Originally posted by pinko_liberal
    I might be wrong but I feel the above means that if my union has (say) two members and I assign a value to one of the members the values of the other members takes unspecified values, so IMHO it rules out assigning a value to one member and assuming that other member's value have changed to particular value ( like assuming in union Quzah defined that the bit field has taken the values of the bit pattern that define the value of char member of the union when the char member is assigned a value). IMHO assigning a value to one member of union and then expecting another member of the union to take a specific value is not safe.
    What are you talking about exactly?
    Code:
    union
    {
        unsigned int b;
        struct {
            unsigned int m00:1;
            ...
            unsigned int m31:1; /* assuming 32 bits */
        } map;
    } u1, u2;
    
    u1.b = 10;
    u2.map.m00 = u1.map.m31;
    ...
    u2.map.m31 = u1.map.m00;
    Now what part in here is supposed to have "unknown" values? Making an assignment from one variable to another does not move that data out of the variable you're assigning from. This behaviour wouldn't ever happen in any implementation of the = operator. At least, that's what I gather you're trying to say happens?

    u2.map.m00 = u1.map.m31;

    You're saying that now "u1.map.m31" doesn't hold any correct data? That it's some how randomized in the assignment process?

    Or are you saying that when we're done that "u2.b" won't hold valid data? It has to. It's like using a void pointer to some spot in memory, writing 4 bytes there one at a time, then using the same void pointer to say it's an integer. It has to work, because it's the same physical space in memory. At least that's my understanding of it and what you're trying to get across.


    Quzah.
    Hope is the first step on the road to disappointment.

  4. #19
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    >>It has to work, because it's the same physical space in memory. <<

    What he is saying is that technically this is not a legal assumption.

    Technically he is right. However, you are unlikely to see a problem in this instance.

    Here's some code to demonstrate:
    Code:
    #include <stdio.h>
    #include <stddef.h>
    
    int main(void) {
    
    	union unTest {
    		struct {
    			char  a;
    			long  b;
    			short c;
    			char  d;
    		} stTest;
    
    		long long llTest;
    	} test;
    
    	printf("%d, %d, %d, %d, %d", sizeof(test), sizeof(test.stTest), sizeof(test.llTest),
    	                             offsetof(union unTest, stTest), offsetof(union unTest, llTest));
    
    	getchar();
    	return 0;
    }
    Code:
    Results(MSVC): 16, 12, 8, 0, 0

  5. #20
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Intel has already provided opcodes to do this. Unfortunately C has no equivalent function but Quzah's is the best solution. For an assembly language solution, which will do this in 4 clock cycles or less look into the RCL, RCR, ROL, and ROR instructions. They rotate bits - the high order bit can be rotated to the low order and vice versa. Using these opcodes with the correct number of rotations will effectively reverse the bits. This can also be used to swap bytes since it would be possible to rotate the value by half of the total bits thus resulting in bytes being reversed.


    START:

    0000 1111

    Rotated left by 4 bits

    1111 0000

    The result is that the low order bits of this byte have been switched with the high order bits of this byte.

    Here is the same operation on a word - shifted left by (numberofbitsindatatype/2)

    0000 1111 1111 0000

    Rotated left by 8 bits

    1111 0000 0000 1111

    If you notice the bytes of this word have been swapped. Now with a simple mov instruction you could save these values. This is the fastest way to swap bytes but you can also swap words, dwords, and even qwords. Just shift left or right by the data type size in bits divided by 2.

    This just swaps bits, it does not reverse them. But reversing can also be done in assembly but prob just as fast in C.

    1000 0111

    0111 1000

    Pretty much a NOT operation isn't it or am I missing something?

  6. #21
    Registered User
    Join Date
    Apr 2004
    Posts
    22
    This is to Alex's responce..

    This is program for swapping the byte. FOr example, 0th bit should be swapped with 7th bit. 1st bit should be swapped with 6th bit and so on. But this particular solution is bit hard for me to analyse. Can anybody analyse this for me????

    Code:
    unsigned char quux(unsigned char value)
    {
       value = ((value&0xaa)>>1) | ((value&0x55)<<1);
       value = ((value&0xcc)>>2) | ((value&0x33)<<2);
       return (value>>4) | (value<<4);
    }

  7. #22
    C++ Developer XSquared's Avatar
    Join Date
    Jun 2002
    Location
    Ontario, Canada
    Posts
    2,718
    >1000 0111
    >0111 1000
    >Pretty much a NOT operation isn't it or am I missing something?
    Yep, you're missing something. They're talking about reversing the order of the bits, not just inverting the bits. Therefore, it should be:
    1000 0111
    1110 0001
    Naturally I didn't feel inspired enough to read all the links for you, since I already slaved away for long hours under a blistering sun pressing the search button after typing four whole words! - Quzah

    You. Fetch me my copy of the Wall Street Journal. You two, fight to the death - Stewie

  8. #23
    Registered User
    Join Date
    Apr 2004
    Posts
    22
    Yep, you're missing something. They're talking about reversing the order of the bits, not just inverting the bits. Therefore, it should be:
    1000 0111
    1110 0001

    This is how it should be but I am not able to analyse the algorithm in following case. Meaning why is he ANDING with AA and 55. AThen OR. Againg ANDING with CC and 33 resectively and the OR each other.

    End result is correct but what is analysis?

    Let e know..

  9. #24
    Registered User alex's Avatar
    Join Date
    Sep 2001
    Posts
    132
    Hi Happy Man!

    The algorithm uses the fact that reversing the bits of a value is the same as splitting the value in two parts (say hi_lo -> hi, lo), reverse the bits of both parts (lets call those rhi, rlo), and concatenating the reversed parts in the reverse order (rhi, rlo -> rlo_rhi)...

    The first line interchanges odd and even bits: "value&0xaa" and "value&0x55" select the even and odd bits of value; the shift operator is used to change the position of the bits, and the or operator (which could just as well have been a xor or a simple add) puts the bits together...

    Code:
    abcdefgh: AND 10101010 -> a0c0e0g0: shift right 1 -> 0a0c0e0g
    abcdefgh: AND 01010101 -> 0b0d0f0h: shift left 1 --> b0d0f0h0
                                                 (or)    --------
                                                         badcfehg
    The second line does the same for pairs of two-bit parts of value.

    The third line does the same for four-bit parts of value, and could be written as "return ((value&0xf0)>>4) | ((value&0x0f)<<4);", but the and-operations are superfluous.

    Now extend this to 16, 32, and 64 bits... Try the same for the other solutions mentioned

    greetings,
    alex

  10. #25
    Registered User
    Join Date
    Apr 2004
    Posts
    22
    Hello Alex,

    Thanks a lot....

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. brace-enclosed error
    By jdc18 in forum C++ Programming
    Replies: 53
    Last Post: 05-03-2007, 05:49 PM
  2. About aes
    By gumit in forum C Programming
    Replies: 13
    Last Post: 10-24-2006, 03:42 PM
  3. Need some help regarding data structures
    By Afrinux in forum C Programming
    Replies: 15
    Last Post: 01-28-2006, 05:19 AM
  4. error: identifier "byte" is undefined.
    By Hulag in forum C++ Programming
    Replies: 4
    Last Post: 12-10-2003, 05:46 PM
  5. sorting a structure of arrays
    By Unregistered in forum C Programming
    Replies: 7
    Last Post: 03-15-2002, 11:45 AM