Bit fields

This is a discussion on Bit fields within the C++ Programming forums, part of the General Programming Boards category; the findfirst and findnext functions populate ffblk structure with file info. One of the ffblk struct element's is ff_ftime which ...

  1. #1
    Registered User
    Join Date
    Oct 2008
    Posts
    10

    Bit fields

    the findfirst and findnext functions populate ffblk structure with file info. One of the ffblk struct element's is ff_ftime which is an unsigned short and, according to the help file (Borland builder 5.0), it contains bit fields for reffering the seconds, minutes and hours:

    ff_ftime and ff_fdate contain bit fields for referring to the current date and time. The structure of these fields was established by the operating system. Both are 16-bit structures divided into three fields.

    ff_ftime:

    Bits 0 to 4 The result of seconds divided by 2 (for example 10 here means 20 seconds)
    Bits 5 to 10 Minutes
    Bits 11 to 15 Hours

    Well, yeah there's ff_fdate too but they're pretty much the same. So... I've checked MSDN what are bit fields - seemed pretty clear, but... as I understood they are used to save some space when using integrals in structures and ff_fdate is not a structure (I think) and I'm lost now.

    I, basicaly, need to extract a viable time from ff_ftime, but for, what is 21:35:47, I get 44152 and for, what is 15:19:36, I get 31347. Halp.

  2. #2
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    I am reading the page you find the information. I believe it doesn't mean bit fields in that sense. Just field of bits, meaning that you can use a mask to take the information you want.
    Like if you want seconds:
    Code:
    ff_ftime t;
    unsigned short SEC_MASK = 15; // 15 = 0..01111
    unsigned short sec = t & SEC_MASK;
    sec *= 2;
    try it

  3. #3
    Registered User
    Join Date
    Oct 2008
    Posts
    10
    It works! But how to get the minutes and hours out? or anything that starts not at the beggining?

  4. #4
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,189
    minutes would be (timecode & 2016) / 32;
    Until you can build a working general purpose reprogrammable computer out of basic components from radio shack, you are not fit to call yourself a programmer in my presence. This is cwhizard, signing off.

  5. #5
    Registered User
    Join Date
    Oct 2008
    Posts
    10
    didn't you mean & 2047?

  6. #6
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    And that's why you should always specify bitmasks in hex.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  7. #7
    Registered User
    Join Date
    Oct 2008
    Posts
    10
    Dude... I'm an amateur, I've started c++ programming 2.5 months ago, before that I only knew only how to create arrays, procedures, functions and write and read from files in pascal. I do not know what bitmasks are, I know what hex is, though. And isn't the time encoded in binary, in this case?

  8. #8
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    Numbers are always "encoded" in binary, as the computer sees it. That's irrelevant when it comes to the programmer reasoning about them, though. Radix is just a display convention; numbers are pure.

    The advantage of hex is that there's a very simple mapping to binary: four binary digits form a single hex digit, always. Thus, it's more compact than binary, and easier to translate than decimal.

    Speaking of binary, here's how bitfields and bitmasks work. Suppose you have a 16-bit integer:
    0000000000000000
    Now, what's stopping you from reinterpreting that? Say, as two 5-bit and one 6-bit integers?
    00000 000000 00000
    When you do that, you've turned the integer into a bitfield. A bitmask then is an integer that you can use in bitwise operations (bitwise-AND, &, usually) to assist you in using the bitfield. The bitmask for the first block above is
    1111100000000000
    For the second block
    0000011111100000
    And so on. It's pretty simple.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  9. #9
    Registered User
    Join Date
    Oct 2008
    Posts
    10
    I see, but wouldn't specifying bitmasks in hex would restrict the masks to be 4*n bits in size, in which case, with time firmats, where numbers don't go higher than 60, would cause empty bits of memory that stay 0 all the time?

    Anyways, I can't get abachlers example to work, do i have to put it like this:
    Code:
    unsigned short sec = (t & 2016) / 32;
    Or?...

    I mean, I understand how the 1 and 0 are placed and I could brew a method that would extract decimals from specific intervals of a binary number, but... what's the shorter way?

  10. #10
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    Quote Originally Posted by Perspektyva View Post
    I see, but wouldn't specifying bitmasks in hex would restrict the masks to be 4*n bits in size, in which case, with time firmats, where numbers don't go higher than 60, would cause empty bits of memory that stay 0 all the time?
    You can only divide bitfields at bit boundaries, obviously, so to represent a second or minute value (0-59) you'll have to use 6 bits (0-63), wasting 4 values.
    Now, the entire mask is restricted to be of an actually supported integer type, as every other integer. I don't know what you mean by the other part. There's no number you can represent in binary that you can't represent in hex.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  11. #11
    Registered User
    Join Date
    Oct 2008
    Posts
    10
    Quote Originally Posted by CornedBee View Post
    You can only divide bitfields at bit boundaries, obviously, so to represent a second or minute value (0-59) you'll have to use 6 bits (0-63), wasting 4 values.
    Now, the entire mask is restricted to be of an actually supported integer type, as every other integer. I don't know what you mean by the other part. There's no number you can represent in binary that you can't represent in hex.
    We're either not on the same page (with me being on a page that doesn't actually exist) or my knowledge backroud is simply too thin for me to understand this stuff. So, maybe, you know how can I extract a decimal value of minutes which resides in the 6th to 11th bit of a 16bit integer... using masks, or some other quicker way.
    A code snippet which would fit nicely in C_ntua's one would be nice.

  12. #12
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    Assuming 0-based counting of bits. You either mask first and then shift, or you shift first and then mask. Shifting first is easier, because the mask always starts at the 0th bit.
    Code:
    unsigned int packed_time = get_a_packed_time();
    unsigned minutes = (packed_time
        >> 6)   // Shift so that 6th to 11th bit are now 0th to 5th
        & 0x1F; // Mask out everything beyond the 5th bit. 0x1F is 0000000000011111
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  13. #13
    Registered User
    Join Date
    Oct 2008
    Posts
    10
    Quote Originally Posted by CornedBee View Post
    Assuming 0-based counting of bits. You either mask first and then shift, or you shift first and then mask. Shifting first is easier, because the mask always starts at the 0th bit.
    Code:
    unsigned int packed_time = get_a_packed_time();
    unsigned minutes = (packed_time
        >> 6)   // Shift so that 6th to 11th bit are now 0th to 5th
        & 0x1F; // Mask out everything beyond the 5th bit. 0x1F is 0000000000011111
    Hehe, it works, I was thinking how to shift binary numbers left and right and I was thinking that you'd have to assign a mask as an interval or smth... anyways It works now and I understand it. Thanks!

  14. #14
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,189
    Quote Originally Posted by Perspektyva View Post
    didn't you mean & 2047?
    no, I didn't, although that woudl work also, I specifically used the number 0000001111100000, although im sure 0000001111111111 woudl also work sicne you are just shifting after that anyway.
    Until you can build a working general purpose reprogrammable computer out of basic components from radio shack, you are not fit to call yourself a programmer in my presence. This is cwhizard, signing off.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. union in struct with bit fields
    By sagarnewase in forum C Programming
    Replies: 4
    Last Post: 05-12-2008, 08:30 AM
  2. Replies: 7
    Last Post: 12-10-2004, 08:18 AM
  3. bit patterns of negtive numbers?
    By chunlee in forum C Programming
    Replies: 4
    Last Post: 11-08-2004, 08:20 AM
  4. Bit Manipulation Questions
    By CPPNewbie in forum C++ Programming
    Replies: 7
    Last Post: 08-12-2003, 03:17 PM
  5. Array of boolean
    By DMaxJ in forum C++ Programming
    Replies: 11
    Last Post: 10-26-2001, 12:45 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