Coverage for MC6809/utils/bits.py: 100%

13 statements  

« prev     ^ index     » next       coverage.py v7.2.1, created at 2023-03-06 19:50 +0100

1#!/usr/bin/env python 

2 

3""" 

4 Utilities around bit manipulations 

5 ================================== 

6 

7 Links: 

8 https://wiki.python.org/moin/BitManipulation 

9 https://wiki.python.org/moin/BitwiseOperators 

10 

11 :created: 2014 by Jens Diemer - www.jensdiemer.de 

12 :copyleft: 2014 by the MC6809 team, see AUTHORS for more details. 

13 :license: GNU GPL v3 or above, see LICENSE for more details. 

14""" 

15 

16 

17def is_bit_set(value, bit): 

18 """ 

19 Return True/False if the bit at offset >bit< is 1 or 0 in given value. 

20 

21 bit 7 | | bit 0 

22 ...10111101 

23 

24 e.g.: 

25 

26 >>> is_bit_set(0x01, bit=0) # 00000001 

27 True 

28 >>> is_bit_set(0xfd, bit=1) # 11111101 

29 False 

30 >>> is_bit_set(int('10000000', 2), bit=7) 

31 True 

32 >>> is_bit_set(int('01111111', 2), bit=7) 

33 False 

34 >>> is_bit_set(int('1111000011110000', 2), bit=11) 

35 False 

36 >>> is_bit_set(int('1111000011110000', 2), bit=12) 

37 True 

38 """ 

39 return False if value & 2 ** bit == 0 else True 

40 

41 

42def get_bit(value, bit): 

43 """ 

44 return 1 or 0 from the bit at the given offset >bit<, e.g.: 

45 

46 >>> get_bit(0x01, bit=0) # 00000001 

47 1 

48 >>> get_bit(0xfd, bit=1) # 11111101 

49 0 

50 >>> get_bit(int('10000000', 2), bit=7) 

51 1 

52 >>> get_bit(int('01111111', 2), bit=7) 

53 0 

54 >>> get_bit(int('1111000011110000', 2), bit=11) 

55 0 

56 >>> get_bit(int('1111000011110000', 2), bit=12) 

57 1 

58 """ 

59 return 0 if value & 2 ** bit == 0 else 1 

60 

61 

62def set_bit(value, bit): 

63 """ 

64 returns an integer with the bit at offset >bit< set to 1. 

65 

66 >>> set_bit(0x00, 2) 

67 4 

68 >>> set_bit(0x00, 7) 

69 128 

70 >>> '{0:08b}'.format(set_bit(int('00000000', 2), bit=5)) 

71 '00100000' 

72 >>> '{0:08b}'.format(set_bit(int('10101010', 2), bit=0)) 

73 '10101011' 

74 >>> '{0:08b}'.format(set_bit(int('1111000011110000', 2), bit=10)) 

75 '1111010011110000' 

76 >>> '{0:08b}'.format(set_bit(int('11111111', 2), bit=3)) 

77 '11111111' 

78 """ 

79 return value | 1 << bit 

80 

81 

82def clear_bit(value, bit): 

83 """ 

84 returns an integer with the bit at offset >bit< set to 0. 

85 

86 >>> clear_bit(128, 7) 

87 0 

88 >>> clear_bit(0, 2) 

89 0 

90 

91 >>> '{0:08b}'.format(clear_bit(int('11111111', 2), bit=5)) 

92 '11011111' 

93 

94 >>> '{0:08b}'.format(clear_bit(int('1111000011110000', 2), bit=13)) 

95 '1101000011110000' 

96 """ 

97 return value & ~(1 << bit) 

98 

99 

100def toggle_bit(value, bit): 

101 """ 

102 >>> toggle_bit(128, 7) 

103 0 

104 >>> toggle_bit(0, 7) 

105 128 

106 

107 >>> '{0:08b}'.format(toggle_bit(int('11111111', 2), bit=5)) 

108 '11011111' 

109 >>> '{0:08b}'.format(toggle_bit(int('11011111', 2), bit=5)) 

110 '11111111' 

111 

112 >>> '{0:08b}'.format(toggle_bit(int('1111000011110000', 2), bit=13)) 

113 '1101000011110000' 

114 >>> '{0:08b}'.format(toggle_bit(int('1101000011110000', 2), bit=13)) 

115 '1111000011110000' 

116 """ 

117 return value ^ 1 << bit 

118 

119 

120def invert_byte(value): 

121 """ 

122 >>> '{0:08b}'.format(invert_byte(int('00001000',2))) 

123 '11110111' 

124 

125 >>> '{0:08b}'.format(invert_byte(int('10101010',2))) 

126 '01010101' 

127 

128 >>> '{0:08b}'.format(invert_byte(int('00110011',2))) 

129 '11001100' 

130 """ 

131 return 2 ** 8 + ~value 

132 

133 

134if __name__ == "__main__": 

135 import doctest 

136 print(doctest.testmod(verbose=0))