作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
假设我将整数视为具有 4 个小数位。现在 0 是零,16 是一,32 是二,然后继续。四舍五入时,[-7, 7]范围内的数字变为0,[8, 23]范围内的数字变为16。
我的代码是这样的:
std::int64_t my_round(std::int64_t n) {
auto q = n / 16;
auto r = n % 16;
if (r >= 0) {
if (r >= 8) {
++q;
}
} else {
if (r <= -8) {
--q;
}
}
return q * 16;
}
如此简单的任务需要大量代码。我想知道是否有更快的方法来做到这一点。我只需要支持 64 位有符号整数。
编辑:有评论(我不记得是谁发表的评论)建议添加 15 并屏蔽低位。它没有用。但经过反复试验,我想到了这个。
std::int64_t my_round2(std::int64_t n) {
if (n >= 0) {
n += 8;
}
else {
n += 7;
}
return n & (~15ll);
}
我不知道。但是 my_round2
似乎给出了与 my_round
相同的结果并且快了 20 倍。如果有办法去掉分支就更好了。
最佳答案
与
return (n + 8 + (n>>63)) & (~15ll);
可以从 my_round2()
中剪掉分支,并确保原始对称性为零。这个想法是 signed type >> (sizeof(signed type) * 8 - 1)
对于负值是 -1,对于正值是 0。
Clang 能够为原始 my_round2()
生成无分支代码,但它仍然比此处建议的例程长一条指令。使用 arm64,节省的钱更多。
关于c++ - 快速舍入定点数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67442712/
我是一名优秀的程序员,十分优秀!