为了账号安全,请及时绑定邮箱和手机立即绑定

如何将 0/1 转换为有效签名?

如何将 0/1 转换为有效签名?

料青山看我应如是 2022-05-24 18:18:42
看下面的函数,其中a是一个无符号字节 0-255,b是一个浮点数:def convert(a, b):    if a & 0x80:        return -b    return bb如果第一个位被设置,它会否定a,但如果不是,则什么都不做。人们可能会认为这不是那么酷,因为条件语句破坏了 CPU 中的分支预测。因此,人们会尝试将其转换为计算。但我只找到了这个解决方案,看起来效率不高:def convert(a, b):    return (-1)**(a & 0x80) * b哪个效率更高?编译器是否简化了第二个?有没有更好的办法?
查看完整描述

2 回答

?
陪伴而非守候

TA贡献1757条经验 获得超8个赞

这是 Python。在您可能想到的意义上,没有编译器。假设您使用的是 CPython(参考解释器),所有内容都通过一个巨大的 switch 语句循环运行,该语句读取并解释每个字节码。您对分支预测的担忧在这里无关紧要;在您执行的每个操作中,在类型检查、动态函数指针查找和调用等之间,都会有六个 CPU 级分支。switch当它最终读取字节码时,远程跳转可能会稍微损害数据缓存几百字节之外,而不是下一个字节码,但分支预测(或缺少分支预测)不是问题(100% 可预测的跳转也会有同样的问题)。

基本上,你在这里所做的任何可能在 C 中工作并被编译器的优化器优化为理想代码的东西在 CPython 中都不起作用。所以不要打扰。编写您的完整代码,如果它太慢,则对其进行分析,然后努力优化“最热门”(最常被调用)的部分。你在这里进行了过早的优化,真的应该停止。

如果我是你,我会选择选项#1(可能替换if a & 0x80:为,if a >= 0x80:因为前者需要返回一个int必须进行更昂贵的真值测试,而后者bool直接返回,这是最便宜的真值测试) ,因为它很简单,不太可能很糟糕;仅当您的程序太慢时才调查其他选项,并且分析表明这段特定的代码是热点


查看完整回答
反对 回复 2022-05-24
?
www说

TA贡献1775条经验 获得超8个赞

(-1)**(a & 0x80)计算功率,所以它非常低效。实际上,您可以将其替换1 if exponent & 1 == 0 else -1为 exponent being a & 0x80。但是通过做从 0 或 1 得到 1 和 -1 更容易x*2 - 1


一些非分支版本


return (((a >> 7) << 1) - 1)*b;

return (((a >> 6) & 0x02) - 1)*b;

return math.copysign(b, -(a >> 7));

return math.copysign(b, -(a & 0x80));


查看完整回答
反对 回复 2022-05-24
  • 2 回答
  • 0 关注
  • 81 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信