« お題6:名簿の並び替え | メイン | 自由投稿 »

お題7:整数とビット列の相互変換

整数とビット列の間を相互変換できる **モジュール** を作れ。 クラスでも、関数の集合でもかまわない。

トラックバック

このエントリーのトラックバックURL:
http://www.nishiohirokazu.org/mt/mt-tb.cgi/606

コメント (6)

匿名:
import struct
struct.pack("i", 100000) #-> '\xa0\x86\x01\x00'

# という感じのものを作れということでしょうか?
海坊主(怠惰版):
from struct import *

# をstolen_struct.pyとして保存すれば、

import stolen_struct
stolen_struct.pack("i", 100000)

# と使える。
海坊主:
# 速度とかは考慮していません。

# my_module.py

_n = 256

def int_to_bits(i):
    def f(i):
        if i < 0:
            signbit = 1
            i = -i
        else:
            signbit = 0
        while i:
            yield i % _n
            i //= _n
        yield signbit

    return "".join(chr(n) for n in f(i))

def bits_to_int(bits):
    result = 0
    for i in xrange(len(bits) - 1):
        result += ord(bits[i]) * (_n ** i)
    if ord(bits[-1]):
        result = -result
    return result

# test

import my_module as m

def main():
    for i in xrange(-1000, 1000 + 1):
        bits = m.int_to_bits(i)
        print i, repr(bits)
        assert m.bits_to_int(bits) == i

if __name__ == '__main__':
    main()

odz:
import sys

def byte2bits(i):
    """
    convert byte as bit list.

    >>> byte2bits(10)
    [0, 0, 0, 0, 1, 0, 1, 0]
    """
    return [(i >> j) & 0x01 for j in reversed(range(8))]

_BYTE_TO_BITS = [byte2bits(i) for i in xrange(0x100)]

def int2bits(i):
    """
    convert integer as bit list.

    >>> int2bits(49015)
    [1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1]
    """
    def f(x):
        while x > 0:
            yield _BYTE_TO_BITS[x & 0xff]
            x >>= 8
    return sum(reversed(list(f(i))), [])
    
def bits2int(bits):
    """
    convert bit list as integer

    >>> bits2int([0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0])
    29556
    """
    return reduce(lambda r, x: r << 1 | x, bits, 0)

def _test():
    import doctest
    doctest.testmod()

if __name__ == '__main__':
    _test()
#素直に
def int2bits(i):
    b = ''
    l = len(str(i))
    idx = 0
    while True:
        b += str((i)&1)
        i >>= 1
        if i == 0:
            break
        idx += 1
    return b[::-1]

def bits2int(b):
    i = 0
    l = len(b)
    for idx,v in enumerate(b):
        i += (int(v)<<(l-(idx+1)))
    return i

def main():
    b = '1111111111111111101101'
    i =  bits2int(b)
    print i
    b = int2bits(i)
    print b
    
    i = 1234567890
    b = int2bits(i)
    print b
    i = bits2int(b)
    print i

if __name__ == '__main__':
    main()
ぎゃあ、
int2bits のl = len(str(i))は不要でした。

コメントを投稿

About

2007年06月11日 19:05に投稿されたエントリーのページです。

ひとつ前の投稿は「お題6:名簿の並び替え」です。

次の投稿は「自由投稿」です。

他にも多くのエントリーがあります。メインページアーカイブページも見てください。

Powered by
Movable Type 3.34