C++/bits

Advertisement


Question
Dear Ralph,

How are you? Sorry that I'm back with bit/byte questions.
Computers usually deal with bytes and these are easy to write.
I, however, need to write bits into binary files that are not multiples of 4 or 8.

What is the easiest way to make a file that contains exactly these three bits (and nothing more): 0,1,0 ?

Thanks,
Andres

Answer
Note: I am assuming you _really_ mean bits and _not_ the characters '0' and '1' here, as each character takes up one byte (at least - depending on encoding).

You cannot. The smallest item you can write to a file is 1 byte of 8 bits. In fact, as disks are usually (always?) block devices, that one byte will be written as part of, and take up on the disk, a whole file system allocation block - which will be at least 1 physical disk sector in size. See http://en.wikipedia.org/wiki/Disk_sector for more on how hard disks are organised into sectors - solid state storage is similar from the programming perspective.

Looking at the basic C file data transfer functions fread and fwrite we see they transfer data between memory and a file - the size information on how much data to transfer is used to calculate the size of the memory to transfer data to / from in terms of char (size of 1 by definition in C and C++) and _not_ in the number of bits.

Likewise, the C++ IOStreams unformatted I/O operations std::istream::read and std::ostream::write transfer to/from memory a number of chars.

Hence you cannot read/write anything less that a byte (or rather, in C/C++, a char, which is in fact 1 byte in size - a byte in C++ being at least 8-bits wide), which, as mentioned will be transferred to block devices as part of a whole block.

Of course you can write a single byte with say, only values ranging from 0..7 (lower 3 bits). Or have 2 3-bit values in a single byte (e.g. bits 0,1,2 and bits 3,4,5) and use bit operations  (shift, bitwise AND, OR  and NOT and bit fields) to insert and extract the raw 3 bit values to/from a byte sized char. Please research these topics to find out more as I am not a full time C/C++ or computer science tutor! [And my system is failing quite a lot at the moment (I am in the process of ordering a new one!) so I think it best to not spend lots of time writing lots of detail at the moment - it could take a long time if my machine keeps crashing!].

Note also the following text early in the C++11 standard (Section 1.7 The C++ memory model, start of paragraph 1):

   "The fundamental storage unit in the C++ memory model is the byte. A byte is at least large enough to contain
    any member of the basic execution character set and the eight-bit code units of the Unicode UTF-8 encoding
    form and is composed of a contiguous sequence of bits, the number of which is implementation defined."

So C++ basically builds its types in terms of _bytes_ and _not_ bits. So you cannot store just 3 bits in memory in C++, which is very reasonable as the machines C++ runs on tend to address data in chunks of 8-bit bytes or larger. You can, as mentioned, store 3 bits within a larger unit - say an 8-bit byte, but the language and the machine programs written in C++ run on work in bytes (or larger!) hence I/O interfaces also tend to work in byte units - even if they are at the lowest level concerned with bits.

Sorry if this rambled on a bit but I am not sure how to explain why you cannot (easily) work in arbitrary bit-widths. If this was not what you were after then please ask another question clarifying my confusion.  

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


Ralph McArdell

Expertise

I am a software developer with more than 15 years C++ experience and over 25 years experience developing a wide variety of applications for Windows NT/2000/XP, UNIX, Linux and other platforms. I can help with basic to advanced C++, C (although I do not write just-C much if at all these days so maybe ask in the C section about purely C matters), software development and many platform specific and system development problems.

Experience

My career started in the mid 1980s working as a batch process operator for the now defunct Inner London Education Authority, working on Prime mini computers. I then moved into the role of Programmer / Analyst, also on the Primes, then into technical support and finally into the micro computing section, using a variety of 16 and 8 bit machines. Following the demise of the ILEA I worked for a small company, now gone, called Hodos. I worked on a part task train simulator using C and the Intel DVI (Digital Video Interactive) - the hardware based predecessor to Indeo. Other projects included a CGI based train simulator (different goals to the first), and various other projects in C and Visual Basic (er, version 1 that is). When Hodos went into receivership I went freelance and finally managed to start working in C++. I initially had contracts working on train simulators (surprise) and multimedia - I worked on many of the Dorling Kindersley CD-ROM titles and wrote the screensaver games for the Wallace and Gromit Cracking Animator CD. My more recent contracts have been more traditionally IT based, working predominately in C++ on MS Windows NT, 2000. XP, Linux and UN*X. These projects have had wide ranging additional skill sets including system analysis and design, databases and SQL in various guises, C#, client server and remoting, cross porting applications between platforms and various client development processes. I have an interest in the development of the C++ core language and libraries and try to keep up with at least some of the papers on the ISO C++ Standard Committee site at http://www.open-std.org/jtc1/sc22/wg21/.

Education/Credentials

©2016 About.com. All rights reserved.