algorithm - 如何有效地移动数字中的小数点直到达到某个阈值
问题描述
假设我有一个双 x,其值 > 0 且 < 100 万。我想将它的小数点左移,直到 > 100 万且 < 1000 万。例如,23.129385 变为 2313938.5。
我现在所做的只是乘以 10 直到达到停止条件。但是我经常执行这个算法,所以如果我能以某种方式优化它会很有帮助。一个恒定时间的解决方案,与 x 的大小无关,显然是理想的,但到目前为止我还没有想出一个。
解决方案
某些语言,例如带有frexp的 C++ ,将二进制指数公开为整数非常便宜。
如果你很幸运,你可以有一个预先计算的查找表pow2to10
,从 2k 可能的二进制指数到它可能的 10 次方。lookup10
为 10 的幂创建另一个查找表。现在您的计算如下所示:
frexp(x , &n);
int i = pow2to10[n];
if (lookup10[i+1] <= x) {
i++;
}
double result = x * lookup10[i];
现在,您有 3 个数组查找、一个比较和一个乘法,而不是一系列乘法。如果您在紧密循环中执行此操作,请将其存储pow2to10
为 的数组short int
,尝试将范围修剪为您需要的范围,并且查找将位于可以适合 L1 缓存的数据结构中。
如果你不是那么幸运,你可以代替重复乘法,只需与一组已知的 10 次幂进行比较。请注意,如果你有高级语言,你可能会发现运行指令的开销超过了节省比较与相乘。进行二进制搜索以减少查找可能很诱人,但我敢打赌线性搜索会更好,因为这有助于分支预测。
推荐阅读
- java - 如何阻止firebase重复我的聊天
- gradle - 如何处理两个 gradle 插件的任务冲突?
- mysql - 获取一定间隔的数据?
- log4j - Hazelcast IMDG 3.12.5 添加 log4j 依赖以支持日志记录
- symfony - 如何在 webpack encore 中设置 config.node
- google-chrome - 在 WSL Ubuntu 上运行“google-chrome”作为 --headless --no 沙箱会产生多个错误 - 如何在 WSL 中使用无头截屏?
- c - 在计算文本文件程序的字符时出现未定义的行为?
- python - 两个张量之间的Pytorch差异
- lua - 使用lua更改属性名称的xml标记
- postgresql - 使用 AWS Aurora PostgreSQL 数据库集群连接到哪个终端节点进行读/写操作