質問

uintlongulong、およびdecimalをIEEE 754の二重浮動小数点値として表す必要があるデータ型変換を実行しています。変換を実行する前に、IEEE 754データ型に値を含めることができないかどうかを検出できるようにします。

ブルートフォースソリューションは、OverflowExceptionを二重に検索するために、キャストの周りにトライキャッチをラップすることです。特定の CLRドキュメントを読むいくつかの変換は例外なく値を静かに変更することを意味します。

このチェックを行うための確実な方法はありますか?実装の容易さよりも完全性を求めています。 IEEE 754の仕様を注意深く読み、マティッサと指数を注意深くチェックする気がします...

私は、整数を正確に表現することに最も関心があり、浮動小数点の精度を失うことは二次的な関心事であると考えなければなりません(まだ検討する価値があります)。

編集: Int32は、IEE-754として完全に表現できます。また、Decimalデータ型は質問の大部分です。

重要な更新:この質問に言及している場合は、次の質問もお読みください: IEEE-754 Double (64ビット浮動小数点)対Long(64ビット整数)の再検討

非常に大きな値もIEEE-754で正確に表すことができるという答えに欠陥があることに注意してください。これは、値が正しく往復することを意味する場合がありますが、私の本来の目的(JavaScriptに往復します)ではありません。

CLRのSystem.Double型には、これらの値が正しく往復できないため、バグがあるようです。

役に立ちましたか?

解決

単純な解決策は次のようなものです( xがintの場合):

if ((int)(double)x != x) { 
  // won't convert
} else {
  // will convert
}

など、長く続きます。

(double)xは、xをintからdoubleに変換します。 (int)は再び変換します。 (int)(double)xはintをdoubleに変換してから逆に変換します。基本的に、コードは、doubleへの変換が可逆的であること(したがって、doubleがintの正確な値を格納できること)をチェックしています。

他のヒント

これは主に、使用している番号の範囲に依存します。 15桁以内であれば( double の場合)、整数の安全側。

基本的に、考慮する必要があるのは有効桁数です。したがって、数字が有効桁数制限よりも小さい限り、正確なままです。それが大きくなると、精度が失われます(整数であっても)。

番号が<!> ltである限り。 2 ^ 53、あなたは通常良いです。

IEEE 754 Doubleには仮数用に52ビットがあり、 integer / long に変換するため、テストは非常に簡単です。整数が52ビット未満しか消費しない場合、問題なくIEEE 754 doubleに変換できるはずです。

intは32ビット、longは64ビットであると仮定します(Javaの場合は確かですが、チェックするのが面倒ではありません)。したがって、intは符号と符号なしの両方で問題なくdoubleに収まります。

ulongの場合、52番目のビットよりも上位のすべてのビットが((aULong <!> amp; <!> amp; 0xFFF0000000000000)== 0)のようになっている場合に限ります。

長い間、あなたはそのサインを考慮に入れなければなりません。 Longは2の補数ですが、IEEE754は(負のビットを持っているだけではない)ため、負のlongから正(* -1)に変換し、正のようにチェックするだけで安全だと思います。そのため、longが負の場合、最初に-1で時間を計ります(正の場合は何もしません)。次に、ulongのように確認します。

これがお役に立てば幸いです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top