小数点以下 8 桁までの可能性のある数値の配列があり、すべての整数になるように乗算できる最小の共通数値を見つける必要があります。これが必要なのは、元のすべての数値をすべて同じスケールに乗算し、整数のみを処理する密閉されたシステムで処理できるようにするためです。その後、結果を取得し、それらを共通の乗数で割って相対的な結果を得ることができます。 .
現在、数値をいくつかチェックして 100 倍または 1,000,000 倍していますが、*sealed システムによって行われる処理は、大きな数値を処理する場合に非常にコストがかかる可能性があるため、目的のためにすべてを 100 万倍にすることはあまり意味がありません。素晴らしいオプションです。概算として、封印されたアルゴリズムは、10 倍するたびに 10 倍のコストがかかると言えます。
私が必要とするものを達成するために、可能な限り最良の結果をもたらす最も効率的なアルゴリズムは何ですか?また、必要なものの数学的な名前や式はありますか?
*封印されたシステムは、実際には封印されていません。私はそのソースコードを所有/維持していますが、その100,000行の独自の魔法であり、バグとパフォーマンスが徹底的にテストされており、フロートを処理するように変更することは多くの理由でオプションではありません. それは、X x Y セルのグリッドを作成し、X x Y の四角形をグリッドにドロップし、「独自の魔法」が発生して結果を吐き出すシステムです。十分な近似です。
これまでのところ、いくつかの良い答えが静かにあり、「正しい」答えをどのように選択すればよいか疑問に思いました. 最初は、各ソリューションを作成してパフォーマンスをテストすることが唯一の公正な方法だと考えていましたが、純粋な速度だけが関連する要因ではなく、より正確なソリューションも非常に重要であることに後で気付きました。とにかくパフォーマンステストを書きましたが、現在、「直感」式を使用して、速度と精度に基づいて正しい答えを選択しています。
私のパフォーマンス テストでは、ランダムに生成された 100 の数値の 1000 の異なるセットを処理します。各アルゴリズムは、同じ乱数セットを使用してテストされます。アルゴリズムは .Net 3.5 で記述されています (ただし、これまでのところ 2.0 と互換性があります)。テストをできるだけ公正にするために、かなりの努力をしました。
- Greg – 大きな数を掛けてから GCD で割る – 63 ミリ秒
- Andy – 文字列解析 – 199 ミリ秒
- Eric – Decimal.GetBits – 160 ミリ秒
- Eric – 二分探索 – 32 ミリ秒
- Ima – 申し訳ありませんが、ソリューションを .Net で簡単に実装する方法がわかりませんでした (あまり時間をかけたくありませんでした)。
- Bill – あなたの答えは Greg の答えにかなり近かったので、実装しませんでした。わずかに高速になると確信していますが、精度が低下する可能性があります。
したがって、Greg の「多数を掛けてから GCD で割る」ソリューションは、2 番目に高速なアルゴリズムであり、最も正確な結果が得られたので、今のところ正しいと呼んでいます。
私は本当に Decimal.GetBits ソリューションを最速にしたかったのですが、非常に遅かったです。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-greig.aspx ですが、その記事を読むたびに目が眩み、最終的に実装を試みる時間がなくなりました。解決。
誰かがより良いものを考えることができれば、私は常に他の解決策を受け入れます.