为何我的Python FizzBuzz实现未出现预期的(有意)溢出?
问题分析与修复:利用位操作实现FizzBuzz的溢出计数问题
核心问题:Python整数无自动溢出特性
你想通过固定位数计数器的溢出实现自动重置,但Python的整数没有固定位数限制,不会像C/C++这类底层语言那样自动截断溢出位。比如你的fizz计数器定义为2位,但当它加到0b11(十进制3)之后,再加1会变成0b100(十进制4),永远不会再等于0b11,这就是后续Fizz判断完全失效的原因。
具体问题与修复步骤
fizz计数器的溢出模拟
要实现2位计数器的循环,每次递增后必须用位掩码& 0b11截断超出2位的部分,这样数值会在0-3之间循环:fizz = (fizz + 0b01) & 0b11当fizz达到3(0b11)时,下一次递增会变成0,重新开始计数。
fizzbuzz计数器的溢出模拟
同理,4位的fizzbuzz计数器需要用& 0b1111做掩码,同时修正你代码里的注释(原注释写的是3-bit,实际是4-bit):fizzbuzz = (fizzbuzz + 0b0001) & 0b1111buzz计数器的逻辑验证
由于5不是2ⁿ-1的形式,你手动重置的逻辑是对的,但要确保判断条件buzz == 0b101(十进制5)触发后,重置为0b000,后续计数才能正常循环。
修正后的完整代码
def fizzBuzz(n): fizz = 0b00 # 2-bit counter (循环范围0-3) buzz = 0b000 # 3-bit counter (手动重置,计数到5) fizzbuzz = 0b0000 # 4-bit counter (循环范围0-15) for i in range(1, n + 1): fizz = (fizz + 0b01) & 0b11 # 递增+掩码模拟溢出 buzz += 0b001 fizzbuzz = (fizzbuzz + 0b0001) & 0b1111 # 递增+掩码模拟溢出 if fizzbuzz == 0b1111: # 计数到15,触发FizzBuzz yield "FizzBuzz" elif fizz == 0b11: # 计数到3,触发Fizz yield "Fizz" elif buzz == 0b101: # 计数到5,触发Buzz yield "Buzz" buzz = 0b000 # 手动重置 else: yield str(i) print(list(fizzBuzz(20)))
测试结果
运行后输出与预期完全一致:
['1', '2', 'Fizz', '4', 'Buzz', 'Fizz', '7', '8', 'Fizz', 'Buzz', '11', 'Fizz', '13', '14', 'FizzBuzz', '16', '17', 'Fizz', '19', 'Buzz']
内容的提问来源于stack exchange,提问作者NyanSequitur
相关产品推荐
相关产品推荐

