Thread: 'splitting' a double

  1. #1
    Registered User
    Join Date
    May 2006
    Posts
    57

    'splitting' a double

    Hello

    Id like to take a double and split it into its 32 bit high and low bits. Id like to be left with 2 pointers to both 'halves'.

    Heres what I'm thinking:
    Code:
    void split(double x) {
    	unsigned int *low_bits  = (unsigned int *)&x;
            unsigned int *high_bits = (unsigned int *)(&x + sizeof(int));
     
    	printf("low = 0x%0000008x\n", *low_bits);
    	printf("high = 0x%0000008x\n", *high_bits);
    }
    So it was called with 0xFFFFFFFF00000000 Id expect to see 0x00000000 and 0xFFFFFFFF printed(or maybe I have it backwards), but I dont. I'm not sure why.

    Thanks

    (Yeah, this is kind of cheesy and probably a bad idea in general but I need something like this for my computer architecture class. Were working with floating points and we can only use ints. This will make life much easier)

  2. #2
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Your problem is the wrong using of pointer arithmetics

    +delta moves pointer not to delta bytes but to delta units, each unit size depends on the pointre type

    So you can use high_bits = low_bits +1;
    Or if you prefer your approach - cast &x to unsinged char before adding sizeof(int)
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  3. #3
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Or something like:
    Code:
            unsigned int *high_bits = ((unsigned int *)(&x)) + 1;
    --
    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.

  4. #4
    Registered Luser cwr's Avatar
    Join Date
    Jul 2005
    Location
    Sydney, Australia
    Posts
    869
    Quote Originally Posted by matsp View Post
    Or something like:
    Code:
            unsigned int *high_bits = ((unsigned int *)(&x)) + 1;
    This is undefined behaviour, as is the original poster's code. You may only use a character pointer. If you have the ISO/IEC 9899:1999 standard handy, see section 6.3.2.3 paragraph 7.

    The following, for example, is well defined:
    Code:
    void split(double x)
    {
        unsigned char *y = (unsigned char *)&x;
        int i;
        for (i = 0; i < sizeof(double); i++)
            printf("%02x", y[i]);
        puts("");
    }

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Correct, but it's only undefined if a double is not aligned to the same as (or a multiple of) "unsigned int", and whilst I'm sure there are machines where such a construction may be the case (someone implementing for example 56 or 80 bit "double" would fall into this category), it is not a common occurrence.

    Does anyone here actually know of (and are actually using, as opposed to knowing of the existence) a machine where this is the case?

    --
    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.

  6. #6
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    Having doubles not on proper boundaries can happen on any machine when reading binary records from a file that were written as such.

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Todd Burch View Post
    Having doubles not on proper boundaries can happen on any machine when reading binary records from a file that were written as such.
    Sure, and then you probably would get integers on unaligned boundaries too - in which case you need to take care of it.

    In the above case, the value is in a parameter to a function, so the address is not dictated by some (unaligned) struct.

    [By the way, if it's strictly necessary for a double to align to a certain boundary, then constructing structs that have such fields unaligned will be "unusable" for any meaningfull purpose].

    In x86, the fields can have any alignment they like, and both integers and doubles will work just fine with that - it will be at somewhat reduced performance, but it will WORK. Other processor architectures may or may not accept data that isn't properly aligned - and this is the main point about it being undefined - the C standard does not want to define what happens if you access a pointer to integer which is not aligned to a "integer-compatible boundary" - it may work just fine, or it may cause an exception in the processor, which leads to the application crashing - or something else may happen [e.g. the data at the nearest aligned address gets used ].

    --
    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.

  8. #8
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by zxcv View Post
    Hello

    Id like to take a double and split it into its 32 bit high and low bits. Id like to be left with 2 pointers to both 'halves'.

    So it was called with 0xFFFFFFFF00000000 Id expect to see 0x00000000 and 0xFFFFFFFF printed(or maybe I have it backwards), but I dont. I'm not sure why.
    You shouldn't expect to see anything like that. Doubles are very different from integer types in memory. If you expect to be able to represent 0 thru 16F's in a double then how do you expect to store 0.1?
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Copying 2-d arrays
    By Holtzy in forum C++ Programming
    Replies: 11
    Last Post: 03-14-2008, 03:44 PM
  2. Conversion From C++ To C
    By dicon in forum C++ Programming
    Replies: 2
    Last Post: 06-10-2007, 02:54 PM
  3. need some help with last part of arrays
    By Lince in forum C Programming
    Replies: 3
    Last Post: 11-18-2006, 09:13 AM
  4. newbie needs help with code
    By compudude86 in forum C Programming
    Replies: 6
    Last Post: 07-23-2006, 08:54 PM
  5. Unknown Math Issues.
    By Sir Andus in forum C++ Programming
    Replies: 1
    Last Post: 03-06-2006, 06:54 PM