Writing Binary Digits to a file

S

Speed

Hi,

I have a 57000 bit long binary number and I want to save it to a file.

At the moment I am using an unsigned char array to store the array and
then fwrite to store it as follows.

fwrite( BinArr, sizeof(unsigned char), 57000, BinFile);

But it is a waste of space as this takes up around 57 KB which if I
could store as bits would only take up around 7 KB.

Could you please tell me if this could be done.

Thanks a ton.
Speed.
 
R

Richard Heathfield

Speed said:
Hi,

I have a 57000 bit long binary number and I want to save it to a file.

At the moment I am using an unsigned char array to store the array and
then fwrite to store it as follows.

fwrite( BinArr, sizeof(unsigned char), 57000, BinFile);

But it is a waste of space as this takes up around 57 KB which if I
could store as bits would only take up around 7 KB.

Could you please tell me if this could be done.

You seem to be using only one bit in each byte of your array. Consider using
more. Putting it another way, use base 256 rather than base 2.
 
C

Christopher Layne

Richard said:
You seem to be using only one bit in each byte of your array. Consider using
more. Putting it another way, use base 256 rather than base 2.

Or just pack 8 bits into a char.
 
N

Nelu

Richard said:
Speed said:


You seem to be using only one bit in each byte of your array. Consider using
more. Putting it another way, use base 256 rather than base 2.

Shouldn't he use UCHAR_MAX+1 or 2^CHAR_BIT instead of 256?
 
R

Richard Heathfield

Nelu said:
Shouldn't he use UCHAR_MAX+1 or 2^CHAR_BIT instead of 256?

Not necessarily. It depends on his requirements. Some people working on
bigbyte systems prefer, when writing to file, to use only the bottom-most 8
bits of each byte, specifically to make it easier to handle that file
should they need to do so on an 8-bits-per-byte system later on. (And they
may well use a transfer program that can be told to transmit only the low 8
bits of each byte.)
 
N

Nelu

Richard said:
Nelu said:


Not necessarily. It depends on his requirements. Some people working on
bigbyte systems prefer, when writing to file, to use only the bottom-most 8
bits of each byte
<snip>

Is it guaranteed that a byte has at least 8 bits?
 
A

Ancient_Hacker

Speed said:
Hi,

I have a 57000 bit long binary number and I want to save it to a file.

At the moment I am using an unsigned char array to store the array and
then fwrite to store it as follows.

fwrite( BinArr, sizeof(unsigned char), 57000, BinFile);

But it is a waste of space as this takes up around 57 KB which if I
could store as bits would only take up around 7 KB.

Could you please tell me if this could be done.

Thanks a ton.
Speed.


You need to pack more bits into a byte, something close to:

unsigned char InData[ SZ];

unsigned char PackedData[ SZ / BitsPerByte + 1 ];

int i, tot, outcount, Limit;

Limit = BitsToEmit;

while( Limit & 7 ) != 0 ) Limit++;

tot = outcount = 0;

for( i=1; i < Limit; i++ ) {
tot = ( tot << 1 ) | ( InData[ i -1] & 1);
if( (i & 7 ) == 0 ) PackedData[ ++outcount ] = tot;
}

lenout = fwrite( PackedData, outcount, 1, f );
 
F

Frederick Gotham

Nelu posted:
Is it guaranteed that a byte has at least 8 bits?

Yes.

#include <limits.h>

#if CHAR_BIT < 8
#error "Could someone please give me a C compiler?"
#endif
 
N

Nelu

Richard said:
Nelu said:


Yes.

Ok. I've found it in the standard. I was living with the wrong
impression that the number of bits in a byte can be less than 8.

Thank you.
 
D

Dave Thompson

On 5 Oct 2006 11:55:38 -0700, "Ancient_Hacker" <[email protected]>
wrote:
You need to pack more bits into a byte, something close to:
But not too close.
unsigned char InData[ SZ];

unsigned char PackedData[ SZ / BitsPerByte + 1 ];

int i, tot, outcount, Limit;

Limit = BitsToEmit;

while( Limit & 7 ) != 0 ) Limit++;
Syntax error, and more directly done as
Limit = (Limit + 7) & ~7U;
or a little less obviously
Limit = -( -(unsigned whatever)Limit & ~7U);
or to allow other BitsPerByte as implied by your declaration
Limit = (Limit + BitsPerByte-1) / BitsPerByte * BitsPerByte;

Or avoid the whole problem by looping up to the exact number and
adding "if leftover i.e. if not exact multiple handle residue" logic.
tot = outcount = 0;

for( i=1; i < Limit; i++ ) {

Off by one, although it only matters in the case where roundup did
nothing, i.e. the input was already a multiple of BitsPerByte.
tot = ( tot << 1 ) | ( InData[ i -1] & 1);
if( (i & 7 ) == 0 ) PackedData[ ++outcount ] = tot;

Use _postinc+ to put the data in the place your fwrite expects it.

Need to reset tot to 0 after storing if using a signed type (as you
are) or if you are using a BitsPerByte smaller than the actual bits in
an unsigned char (unlikely) AND it matters whether those additional
bits are set effectively to garbarge (depends).
}

lenout = fwrite( PackedData, outcount, 1, f );

Misleading name for the result, which is either 1 (succeeded entirely)
or 0 (failed anywhere). If you actually want the length written (which
is rarely useful) use fwrite (data, 1, outcount, f).

- David.Thompson1 at worldnet.att.net
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,163
Latest member
Sasha15427
Top