0

わかりました、最初の関数は次のようになります。

let dlth x = float (x.ToString().Length)

これは float を取り、桁数を返します。その部分は正常に機能します。2 番目の関数は次のようになります。

let droot x = ((x ** (1./(dlth x))) % 1.)

これは float を取り、それを 1.0/(桁数) に等しい累乗に上げ、結果を取り、係数 1.0 を実行します。整数の場合、これはゼロでなければなりません。

したがって、droot 36 の場合、(36.0 ** (1.0/2.0)) が必要です。これは 6.0 であり、6.0 mod 1.0 は 0.0 に等しくなります。

これで、81.0 という数値を試すところまで問題なく動作します。(および動作するはずの 81 より大きいすべての数値) 何らかの理由で 1.0 を返し、パターン マッチングを無効にします。なぜこれが起こっているのか誰か教えてもらえますか?

PostScript: これは Project Euler ソリューションの一部です。問題がわかっている場合は、Project Euler のソリューションを投稿しないでください。モジュラスが面白い結果を返す理由を理解するのに助けが必要です

4

3 に答える 3

8

浮動小数点演算は、どの言語でも危険にさらされています。私の箱に

printfn "%f" (0.9999999999999 % 1.0)        

プリント

1.000000

うまくいけば、それはあなたを正しい方向に導くのに役立つでしょう。浮動小数点数が「整数」であるかどうかを本当に知りたい場合は、たとえば、最も近い整数を減算し、絶対値がイプシロン(たとえば、0.00001)よりも小さいかどうかを確認するのが適切です。

于 2009-08-11T14:04:01.167 に答える
1

浮動小数点の不正確さが得られる場合は、.NET のdecimalデータ型 (基数 10 で表現可能なすべての数値を表現できる) を使用すると、パフォーマンスが低下する可能性があります。それ以外は、より精度の高い ( double) または整数演算を使用します。

于 2009-08-11T15:21:06.377 に答える
0

正確な浮動小数点表現に依存することは危険であるというブライアンの意見には同意しますが、問題を再現することはできません。私にとってdroot 81.0は、 の期待される結果が得られ0.0ます。F# のどのバージョンを使用していますか? .NET または Mono で実行していますか?

于 2009-08-11T15:17:17.163 に答える