質問

こんにちは。DataSet の DataTable から DataRow を取り出しました。SQL で float データ型として定義されている列にアクセスしています。その値をローカル変数 (C# float データ型) に代入しようとしていますが、InvalidCastExecption が発生します。

DataRow exercise = _exerciseDataSet.Exercise.FindByExerciseID(65);
_AccelLimit = (float)exercise["DefaultAccelLimit"];  

さて、これをいじってみたところ、うまくいきましたが、意味がないし、正しくないと感じました。

_AccelLimit = (float)(double)exercise["DefaultAccelLimit"];

ここで私が欠けているものを誰かが説明できますか?

役に立ちましたか?

解決

SQL float は、以下によれば double です。 SQLDbType のドキュメント.

他のヒント

SQL の float は、 ダブル CLR (C#/VB) で。あるよ SQL データ型と同等の CLR のテーブル MSDN で。

また、通常、SQL Server (または実際) でデータに対して数学計算を実行する場合は、float を使用したくないでしょう。これは、float は不正確なデータ型であり、計算エラーが発生するためです。精度が必要な場合は、代わりに 10 進データ型を使用してください。

Microsoft SQL Server の float は、C# の Double に相当します。その理由は、浮動小数点数は 10 進数のみを近似できるためです。 精度 浮動小数点数の精度によって、その数値の精度が決まります。 近似値 10 進数。Double 型は、負の 1.79769313486232e308 から正の 1.79769313486232e308 までの範囲の値を持つ倍精度 64 ビット浮動小数点数、および正または負のゼロ、PositiveInfinity、NegativeInfinity、Not-a-Number (NaN) を表します。

主な質問はここで答えられていると思いますが、これが機能するという質問のセクションに何かを追加する必要があると感じます。

_AccelLimit = (float)(double)exercise["DefaultAccelLimit"];

これが「機能する」理由と「正しく感じられない」理由は、2 番目のキャスト (左側のもの) によって double を float にダウングレードしているため、精度が失われ、事実上コンパイラーにそのことを伝えているためです。返された値を切り捨てても問題ありません。

この行の言葉で言えば...オブジェクトを取得します(この場合、ダブルを保持します)オブジェクトをダブル(すべてのオブジェクトラップを失う)にダブルをフロート(ダブルのすべての細かい精度を失う)にキャストします)

例えば値が0.0124022806089461と言って上記を行う場合、Accellimitの値は0.01240228になります

それは、C# の float が double 値から取得できる範囲であるためです。これは危険な行為であり、四捨五入ではなく切り捨てであると確信していますが、私には確信が持てないので、誰かがこれを確認したいと思うかもしれません。

「適切ではない」理由は、C# が同じ構文を使用しているためです。 開梱する そしてのために 鋳造, 、これら 2 つはまったく異なるものです。 exercise["DefaultAccelLimit"] オブジェクトとしてボックス化された double 値が含まれています。 (double) する必要があります 箱から出す オブジェクトを double に戻します。の (float) その前に キャスト double を float 値に変換します。C# ではボックス化とキャストを同じ操作で実行できないため、ボックス化を解除してからキャストする必要があります。

キャストが非破壊的である場合でも同様です。float が double にキャストするオブジェクトとしてボックス化されている場合は、次のようにします。 (double)(float)object_var.

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