こんにちは、DataSetからDataTableからDataRowを引き出しました。 SQLでfloatデータ型として定義されている列にアクセスしています。その値をローカル変数(c#floatデータ型)に割り当てようとしていますが、InvalidCastExecptionを取得しています
DataRow exercise = _exerciseDataSet.Exercise.FindByExerciseID(65);
_AccelLimit = (float)exercise["DefaultAccelLimit"];
さて、これで遊んでみましたが、うまくいきましたが、意味をなさず、正しく感じませんでした。
_AccelLimit = (float)(double)exercise["DefaultAccelLimit"];
誰も私がここに欠けているものを説明できますか?
SQLDbTypeのドキュメント に従って、SQLフロートはdoubleです。
SQLのフロートは、CLR(C#/ VB)の Double です。 MSDNには CLRと同等のSQLデータ型のテーブル があります。
また、データが不正確なデータ型であり、計算エラーが発生するため、データに対して数学計算を実行する予定がある場合、通常はSQL Server(または実際)でfloatを使用することはありません。精度が必要な場合は、代わりにdecimalデータ型を使用してください。
Microsoft SQL Serverのfloatは、C#のDoubleと同等です。この理由は、浮動小数点数は10進数にしか近似できないため、浮動小数点数の精度は、その数値近似 10進数の精度を決定するためです。 Double型は、負の1.79769313486232e308から正の1.79769313486232e308の範囲の値と、正または負のゼロ、PositiveInfinity、NegativeInfinity、Not-a-Number(NaN)の範囲の倍精度64ビット浮動小数点数を表します。
「気分が悪い」という理由は、C#がnboxingとcastingに同じ構文を使用しているためです。 exercise["DefaultAccelLimit"]
には、オブジェクトとしてボックス化されたdouble値が含まれます。 (double)
は、nboxからオブジェクトをdoubleに戻すために必要です。 (float)
その前にcasts doubleからfloat値へ。 C#では、同じ操作でボックス化とキャストが許可されていないため、ボックス化を解除してからキャストする必要があります。
キャストが非破壊的であっても同じことが当てはまります。 floatをdoubleにキャストしたいオブジェクトとしてボックス化した場合、次のようにします:(double)(float)object_var
。
主な質問はここで回答されたと思いますが、これが機能することを示す質問のセクションに何かを追加する必要があります。
_AccelLimit =(float)(double)exercise ["DefaultAccelLimit"];
これが「機能する」理由と「正しくない」理由は、2番目のキャスト(左側のキャスト)でdoubleをfloatにダウングレードしているため、精度を失い、コンパイラーにそれを効果的に伝えているためです。返される値を切り捨てても構いません。
この行の状態の言葉で...オブジェクトを取得する(この場合はたまたまdoubleを保持する)オブジェクトをdoubleにキャストする(すべてのオブジェクトのラッピングを失う)doubleをfloatにキャストする(すべての細かい精度を失うダブル)
例えば値が0.0124022806089461で、上記を実行する場合、AccelLimitの値は0.01240228になります
それは、c#のfloatがdouble値から取得できる範囲です。それは危険なことであり、丸めよりも切り捨てであることはかなり確かですが、よくわからないので誰かがこれを確認したいと思うかもしれません。