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