Thread: saving specific bits from a 64-bit number

  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
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    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
    28,413
    Quote Originally Posted by Nominal Animal
    That looks like C++, not C. You're in the wrong forum.
    Indeed, and... moved.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    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,318
    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をこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    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, 08:24 AM
  2. Number of bits in types
    By TriKri in forum C Programming
    Replies: 7
    Last Post: 12-02-2006, 12:56 PM
  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