1

I have an issue. I tryed to save my BitArray object into file. After that I want to read it and get the same BitArray object what I saved earlier. But result is not same with input.

from bitarray import bitarray

a = bitarray()
a += bitarray('{0:014b}'.format(15))
print(a.to01(), len(a))
with open('j.j', 'wb') as file:
    a.tofile(file)
b = bitarray()    
with open('j.j', 'rb') as file:
    b.fromfile(file)
print(b.to01(), len(b))

Output:

00000000001111 14
0000000000111100 16

I see my object now is 2-byte representation. But I want to get 14-bit I saved. Do you have any ideas to make it right?

4
  • 2
    Can you give some context why it is important? Files are stored in bytes. The only way to store exactly 14 bits is to store meta info in the same file indicating only 14 bits should be considered - which doesn't save any space. In fact, in most cases the file will physically use at least 4kb of space. Commented May 23, 2022 at 14:47
  • @marat I want to realize my own compress algorithm, that's why i need to store exect number of bits) I got it. Files are a bytes) Not bits. I will save a number of ending zeroes as 3-bits number at the beggining of my file which i need to delete before reading my encoded file. Commented May 23, 2022 at 15:03
  • Reverse it in and reverse it out. Voila' , zeroes end up on the left. Commented May 23, 2022 at 15:19
  • If all you need is a serialization format, and you don't particularly care about how, then pickle.loads(pickle.dumps(a)) == a should work fine. Commented May 23, 2022 at 15:42

2 Answers 2

0

This isn't a great solution, but it does get rid of the 0's on the right.

from bitarray import bitarray

a = bitarray('{0:014b}'.format(15))

print(a.to01(), len(a)) #00000000001111 14

with open('j.j', 'wb') as file:
    a.reverse()
    a.tofile(file)
       
b = bitarray()

with open('j.j', 'rb') as file:
    b.fromfile(file)
    b.reverse()
    
print(b.to01(), len(b)) #0000000000001111 16

You could skip the reversals and just right shift b, but you would have to create a dynamic system that knows exactly how many bits to shift by. Another solution is to simply use bits in multiples of 8 in the first place. What are you saving here by removing 1 to 7 bits? You aren't saving anything in the file. Those bits will be padded regardless.

Sign up to request clarification or add additional context in comments.

3 Comments

My decoding algorithm reads bits sequence until EOF, that's why i don't need to see those zeroes at the end) You are right, removing 1 to 7 bits it's nothing for compression. it's something for decoding algorithm)
@kanvull I understand what you are saying, but you are forcing yourself to jump through hoops just to use an awkward number of bits. I will restate my earlier question differently: How is using 14 bits instead of 16 beneficial, especially considering that you will end up with 16 bits to manage regardless?
My decoding algorithm works this way: ` while position < bites_count: flag = bites_sequence[position:position+2] position += 2 ` and zeroes at the and will prevent me from doing it right. Cause of index above bound problem
0

It's eather not a great solution, but it's a solution)

def encode():
   encoded_bits = bitarray()
   ...
   encoded_bits += bitarray('000') # 48:51 slice
   zeroes_at_the_end = 8 - len(encoded_bits) % 8
   if zeroes_at_the_end < 8:
      encoded_bits[48:51] = bitarray('{0:03b}'.format(zeroes_at_the_end)) 

def decode(bites_sequence):
   zeroes_at_the_end = ba2int(bites_sequence[48:51])
   if zeroes_at_the_end != 0:
        del bites_sequence[-zeroes_at_the_end:] 

I just contain number of zeroes, which will appear after save/read in files and then easy delete those zeroes

2 Comments

Neither of us have a good solution, but this is far more contrived than simply reversing the bits. Also, look how much stuff you have to do just to use 14 bits instead of 16. Why not use 16 bits and simply ignore the top 2 MSb's?
the problem is, i don't know how much zeroes at the end i need to delete

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.