saving specific bits from a 64-bit number

This is a discussion on saving specific bits from a 64-bit number within the C++ Programming forums, part of the General Programming Boards category; Hello, I have a 64-bit uint64_t number: Code: Primitive<uint64_t> b = 0xCCCCCCCC00000000; I need to save the first 31 (most ...

  1. #1
    Registered User
    Join Date
    Jun 2013
    Posts
    27

    saving specific bits from a 64-bit number

    Hello,

    I have a 64-bit uint64_t number:

    Code:
    Primitive<uint64_t> b = 0xCCCCCCCC00000000;
    I need to save the first 31 (most important) bits - 7FFFFFFE.

    I found this solution in the Internet:

    Code:
    start = (((b)>>(first)) & ((1<<(((last+1)-(first))))-1));
    but in my case for this code:

    Code:
    Primitive<uint64_t> start = (((b)>>(32)) & ((1<<(((63+1)-(32))))-1));
    I get an error: left shift count >= width of type

    And even if I change 63 to 62:

    Code:
    Primitive<uint64_t> start = (((b)>>(32)) & ((1<<(((62+1)-(32))))-1));
    I get: error: integer overflow in expression

    Any tips? Thanks.

  2. #2
    Registered User
    Join Date
    Oct 2011
    Posts
    826
    That looks like C++, not C. You're in the wrong forum.

    In C, the 31 most significant bits of a uint64_t value are simply b shifted right (64-31)=33 bits:
    Code:
    uint64_t result = (uint64_t)value >> 33U;
    In general, the right shift count is (number of bits - number of highest bits needed).

    If you want to (further) limit the result to fewer bits, mask with ((((type)1) << bits)-1). This works, because mathematically that is 2bits-1, which in binary has bits least significant bits set.

    In C, you need to cast to type (uint64_t, above), so that the shift is done with the desired result type. Logically, you need value to first be converted to the result type, and then operated on, not the other way around.

    For example, this copies length bits starting from offset (least significant bit numbered 0), into the least significant bits in the result:
    Code:
    uint64_t copybits(const uint64_t value, const unsigned char offset, const unsigned char length)
    {
        if (length < 64U)
            return (value >> offset) & ( ( (uint64_t)1 << length) - 1 );  
        else
            return (value >> offset);
    }
    The if clause is needed, because (uint64_t)1 << 64) overflows. (It is not used always in practice, because practically all architectures use two's complement rules, and wraparound such that ((uint64_t)1 << 64)-1 == (uint64_t)-1 == ~(uint64_t)0 = all bits set.

    With the if clause, the above works on all architectures, and is not dependent on byte order (little or big endian) or even on internal representation of integers. You only need to remember that regardless of byte order, the above uses offset 0 for the least significant bit, increasing towards more important bits (63 for the most significant bit in an uint64_t), and returns the result in least significant bits.

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,401
    Quote Originally Posted by Nominal Animal
    That looks like C++, not C. You're in the wrong forum.
    Indeed, and... moved.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,292
    Or instead of (uint64_t)1 you can just write 1ULL.
    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"

  5. #5
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,421
    C casts are evil. Seriously. You should use C++ casts. For more information, see Stephan T. Lavavej - Core C&#43;&#43;, 8 of n | C9 Lectures: Stephan T. Lavavej - Core C&#43;&#43; | Channel 9.
    Part 7 is also informative since it deals with signed and unsigned issues and conversions between different integer data types.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Registered User
    Join Date
    Jun 2013
    Posts
    27
    thanks!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 12-01-2009, 07:24 AM
  2. Number of bits in types
    By TriKri in forum C Programming
    Replies: 7
    Last Post: 12-02-2006, 11:56 AM
  3. Counter the number of 1 bits?
    By gqchynaboy in forum C++ Programming
    Replies: 30
    Last Post: 04-04-2005, 07:07 AM
  4. Number of set bits
    By Roaring_Tiger in forum C Programming
    Replies: 8
    Last Post: 09-22-2004, 09:05 PM
  5. copy some bits into a 8 bits binary number
    By Unregistered in forum C Programming
    Replies: 6
    Last Post: 05-29-2002, 10:54 AM

Tags for this Thread


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21