如何不使用算术运算从卢比数值中拆分卢比与派萨?
用位运算替代算术运算拆分卢比和派萨数值
我有一个UInt32类型的数值let value: UInt32 = 6500085,规则是最后两位代表派萨(这里是85),剩下的部分是卢比(这里是65000),而且派萨的值只能是0、5、10…95这类5的倍数。我需要把它转换成价格字符串,不想用Double类型。
目前已经用算术运算实现了:
let price: UInt32 = 6500085 // ₹65000.85 let paisa: UInt32 = price % 100 let rupee: UInt32 = price / 100 let string = "\(rupee).\(paisa)"
我好奇能不能用位运算替代算术运算,觉得位运算性能更好,但试了下面的代码发现不对:
let value: UInt32 = 6500085 let paisa = value & 0xFF let rupee = (value >> 8) print("Rupee: \(rupee), Paisa: \(paisa)")
问题分析与解决方案
首先要明确:你的位运算代码出错的核心原因是100不是2的整数次幂。& 0xFF本质是取模256,而我们需要的是取模100;>> 8等价于除以256,和我们需要的除以100逻辑完全不匹配,结果自然不对。
能不能用位运算实现?
可以,但因为100和2的幂无关,需要结合派萨是5的倍数这个规则做额外处理。不过先强调:现代编译器会自动优化算术运算(比如/100、%100),性能和位运算几乎无差别,完全没必要刻意替换。如果一定要手写位运算,思路如下:
因为派萨是5的倍数,我们可以把整个数值转换成“5派萨”为单位的计数:
- 总单位数 = 原始数值 / 5
- 派萨部分 = (总单位数 % 20) * 5 (20个5派萨刚好是100派萨,即1卢比)
- 卢比部分 = 总单位数 / 20
而除以5、20这类操作,可以用位运算近似(编译器其实也会自动做这个优化),手动实现代码如下:
let value: UInt32 = 6500085 // 用位运算实现 value / 5:(value * 4194304) >> 23 等价于 value / 5 let units = (value * 4194304) >> 23 let paisa = (units % 20) * 5 let rupee = units / 20 let priceString = "\(rupee).\(paisa)" print(priceString) // 输出:65000.85
关键提醒
手动写位运算不仅没有性能优势,还会降低代码可读性,增加维护成本。算术运算的写法已经足够简洁高效,推荐继续使用原来的实现。
内容的提问来源于stack exchange,提问作者NoLoc
相关产品推荐
相关产品推荐

