小数をINT32として保存できるかどうかを判断します
質問
私はいくつかのカスタムシリアル化を行っています。スペースを節約するために、可能であれば価値がある場合は、小数をintとしてシリアル化したいと思います。私は大量のデータを扱っているので、パフォーマンスは懸念事項です。私が使用している現在の方法は次のとおりです。
if ((value > Int32.MinValue) && (value < Int32.MaxValue) && ((valueAsInt = Decimal.ToInt32(value)) == value))
{
return true;
}
これを改善できますか?
解決
ネガティブな値はありますか? MinValueチェックがあるので、はいを推測しています。そうしないと、スキップできます。符号なしのINTを使用することもできます。これにより、より多くの二重値をINTに変換することもできます。
編集: また、より正の数字がある場合は、最初の2つの条件を交換できます。そうすれば、最初のものは失敗する可能性が最も高く、比較の総数が減少します。
他のヒント
あなたの無効化基準は次のとおりです。
1)MaxValueよりも大きいですか?
2)MinValueよりも小さいですか?
3)分数コンポーネントが含まれていますか?
あなたはそれらをカバーしているように聞こえます。私の実装は次のとおりです。
public bool IsConvertibleToInt(decimal value)
{
if(value > int.MaxValue)
return false;
if(value < int.MinValue)
return false;
if(Math.Floor(value) < value && Math.Ceiling(value) > value)
return false;
return true;
}
これはどう。より少ない操作が必要だと思います(少なくとも比較の数は少なくなります):
return (value == (Int32)value);
また、覚えておいてください if
ステートメントは単にブール値を返すだけで、比較を返すことができます。それだけでそれをより速くするかもしれません(コンパイラーがすでにこれを最適化しない限り)。 IFステートメントを使用する必要がある場合は、同様にこれを行うことができます。
if (value == (Int32)value)
{
//Do stuff...
return true;
}
else
{
//Do stuff...
return false;
}
編集: これは実際には機能しないことに気付きました。 Int32キャストは小数から最初の32ビットでコピーして、残りのビットを残しておく(例外を投げない)と思っていましたが、悲しいかな、それはそのように機能しませんでした(言うまでもなく、それは間違っているでしょう。すべての負の値)。
それは、あなたが持っているか、本当に気にかけている小数点以下の場所に依存します。私が最大3桁の場所しか関心がないと言えば、int32で保存できる最大数はint.maxvalue / 1000です。正の数だけで作業している場合は、uintを使用してより多くの数字を得ることができます。いずれにせよ、それを行う方法は、小数点のために一貫してスペースを確保し、 * 1000を使用してそれらをエンコードし、 / 1000を使用して10進みにdecodeすることです。
「valueasint =」は必要ありません。 (Decimal.toint32(value)== value))は、1つの割り当てで同じ結果を得ると思います。 ValueAsintを何らかの出力パラメーターとして使用していますか?
次のようなことをすることはできませんか:
if(Decimal.ToInt32(value) == value)
{
return true;
}
.NETの専門家ではありませんが、それが必要だと思います。また、MIN/Max値も有効であるため、2つの比較オペレーターは「または等しく」する必要があります。
編集:コメントで指摘されているように、これは例外を投げかけます。例外をキャッチして虚偽を返すことを試みることができますが、その時点では、自分で最小/最大テストを行う方がはるかに速いでしょう。