我有一个可能最多有 8 位小数的数字数组,我需要找到可以将它们相乘的最小公共数,以便它们都是整数。我需要这个,以便所有原始数字都可以乘以相同的比例,并由仅处理整数的密封系统进行处理,然后我可以检索结果并将它们除以公共乘数以获得相对结果。
目前我们对数字进行一些检查并乘以 100 或 1,000,000,但是在处理大数字时,*密封系统完成的处理可能会变得相当昂贵,因此仅仅为了它而将所有内容乘以 100 万并不是真的一个很好的选择。作为近似值,假设每次乘以 10 倍,密封算法的成本就会增加 10 倍。
什么是最有效的算法,它也会给出最好的结果,以完成我所需要的,并且是否有我需要的数学名称和/或公式?
*密封系统并不是真正密封的。我拥有/维护它的源代码,但它有 100,000 多行专有魔法,并且已经过彻底的错误和性能测试,出于多种原因,改变它来处理浮动并不是一个选择。它是一个创建 X × Y 单元格的系统,然后将 X × Y 的矩形放入网格中,发生“专有魔法”并输出结果 - 显然这是现实的一个极其简化的版本,但它是一个足够好的近似值。
到目前为止,有一些很好的答案,我想知道我应该如何选择“正确”的答案。首先,我认为唯一公平的方法是创建每个解决方案并对其进行性能测试,但后来我意识到纯粹的速度并不是唯一的相关因素 - 更准确的解决方案也非常相关。无论如何,我编写了性能测试,但目前我正在使用“直觉”公式根据速度和准确性选择正确的答案。
我的性能测试处理 1000 个不同的组(每组 100 个随机生成的数字)。
每个算法都使用同一组随机数进行测试。
算法是用 .Net 3.5 编写的(尽管到目前为止与 2.0 兼容)
我非常努力地让测试尽可能公平。
- Greg – 乘以大数
然后除以 GCD – 63
毫秒
- Andy – 字符串解析
– 199 毫秒
- Eric – Decimal.GetBits – 160 毫秒
- 埃里克 – 二分搜索 – 32
毫秒
- Ima——抱歉我不能
弄清楚如何实施你的
在.Net中轻松解决方案(我没有
想要花太长时间在上面)
- 比尔 – 我觉得你的回答很漂亮
接近格雷格所以没有实施
它。我确信它会快一点
但可能不太准确。
因此,Greg 的“乘以大数,然后除以 GCD”解决方案是第二快的算法,它给出了最准确的结果,所以现在我认为它是正确的。
我真的希望 Decimal.GetBits 解决方案是最快的,但它非常慢,我不确定这是否是由于 Double 到 Decimal 的转换或位掩码和移位所致。应该有一个
使用 BitConverter.GetBytes 的直接 Double 的类似可用解决方案以及此处包含的一些知识:http://blogs.msdn.com/bclteam/archive/2007/05/29/bcl-refresher-floating-point-types-the-good-the-bad-and-the-ugly-inbar-gazit-matthew-格雷格.aspx http://blogs.msdn.com/bclteam/archive/2007/05/29/bcl-refresher-floating-point-types-the-good-the-bad-and-the-ugly-inbar-gazit-matthew-greig.aspx但每次读到那篇文章时,我的目光总是呆滞,最终我没有时间尝试实施解决方案。
如果有人能想到更好的东西,我总是愿意接受其他解决方案。