C#で10進数をintに変換するにはどうすればよいですか?


227

10進数をintに変換するにはどうすればよいですか?


11
最も近い整数に丸めるか、または小数点以下の数値を単に落とすか(つまり、常に
Dinah

128
正直、正真正銘の質問に反対票を投じる意味がわかりません。はい、答えはグーグルで見つけることができますが、人々が1つおきの質問を閉じるのをやめた場合、それは単にサイトの品質を向上させませんか?この質問がスパムや何かであるようではなく、多くの新規参入者がc#に役立つと確信しています
jay_t55

回答:


268

使用Convert.ToInt32からmscorlibのように、

decimal value = 3.14m;
int n = Convert.ToInt32(value);

MSDNを参照してください。も使用できますDecimal.ToInt32。再度、MSDNを参照してください。最後に、次のようにダイレクトキャストを行うことができます

decimal value = 3.14m;
int n = (int) value;

明示的なキャスト演算子を使用しています。MSDNを参照してください。


10
注意:Convertには、特定の変換(nullvs. 0vs. "")に対していくつかの驚くべき動作があります。柔軟性を絶対に必要としない限り(つまり、動的に型付けされたシナリオで)、Convertを使用しないことをお勧めします
Eamon Nerbonne

1
これは、decimal.MaxValueやdecimal.MinValueなどの値では機能せず、結果は-1になるため、-1 OverflowException。私は@Willがここで良い答えを得たと判断しているstackoverflow.com/a/501165/39532
mezoid

8
Convert.ToInt32Decimal.ToInt32動作が異なるため、注意してください。MSDNから:Decimal.ToInt32-戻り値は10進値の整数部分です。小数桁は切り捨てられます。Convert.ToInt32-戻り値は最も近い32ビット符号付き整数に丸められます。値が2つの整数の中間にある場合は、偶数が返されます。、4.5は4に変換され、そして5.5を6に変換される
vezucci

67

できません。

さて、あなたはもちろん可能性は、しかし、INT(可能System.Int32)可能なすべての小数の値を保持するのに十分な大きさではありません。

つまり、int.MaxValueより大きい小数をキャストするとオーバーフローし、小数がint.MinValueより小さい場合はアンダーフローします。

アンダーフロー/オーバーフローするとどうなりますか?2つのうちの1つ。ビルドがチェックされていない場合(つまり、CLRがチェックしない場合)、アプリケーションは値がオーバーフローまたはアンダーフローした後も続行しますが、intの値は期待したものではありません。これは断続的なバグにつながる可能性があり、修正が難しい場合があります。アプリケーションは不明な状態になり、アプリケーションで作業している重要なデータが破損する可能性があります。良くない。

アセンブリがチェックされている場合(プロパティ->ビルド->詳細->算術オーバーフロー/アンダーフローのチェック、または/ checkedコンパイラオプション)、アンダー/オーバーフローが発生すると、コードは例外をスローします。これはおそらくないよりはましです。ただし、アセンブリのデフォルトでは、オーバーフローまたはアンダーフローをチェックしません。

本当の質問は「あなたは何をしようとしているのですか?」です。要件を知らなければ、明白なことを除いて、誰もこのケースで何をすべきかをあなたに言うことができません:それをしないでください

特に気にしない場合、ここでの回答は有効です。しかし、あなたがすべき通信オーバーフローが発生する可能性があることをご理解し、それがあなたにキャストコードをラップすることにより、関係ないことをチェックしないブロック

unchecked
{
  // do your conversions that may underflow/overflow here
}

そうすれば、あなたの後ろに来る人はあなたが気にしないことを理解し、将来誰かがあなたのビルドを/ checkedに変更しても、コードが予期せず壊れることはありません。

場合あなたがしたいすべてが不可欠な部分を残して、数の小数部分を落としている、あなたはMath.Truncateを使用することができます。

decimal actual = 10.5M;
decimal expected = 10M;
Assert.AreEqual(expected, Math.Truncate(actual));

3
入力が10進数の場合、内部では同じものだと思いますが、Math.TruncateよりもDecimal.Truncateを使用した方が快適です。後者はdoubleも受け入れて、偶数を切り捨てることができるためです。これは、10進数の真の切り捨てであるDecimal.Truncateとは対照的に、10進数ではありません。
ブライアン

7
チェックされていないコンテキストは小数には適用されません。小数の演算は、関係なくOverflowExceptionsをスローします。
デイブ

46
int i = (int)d;

端数は切り捨てられます。

最も近い偶数に丸めたい場合(つまり、>。5は切り上げられます)を使用できます

int i = (int)Math.Round(d, MidpointRounding.ToEven);

一般に、C#ではすべての数値型の間でキャストできます。キャスト中に失われる情報がない場合は、暗黙的に行うことができます。

int i = 10;
decimal d = i;

ただし、必要に応じて明示的に行うこともできます。

int i = 10;
decimal d = (decimal)i;

ただし、キャストを通じて情報が失われる場合は、明示的に行う必要があります(情報が失われる可能性があることを示すため)。

decimal d = 10.5M;
int i = (int)d;

ここでは、「。5」を失っています。これは問題ないかもしれませんが、情報を失う可能性があることを示すために、明示的にキャストして明示的なキャストを行う必要があります。


1
:あなたがここにサンプル出力を見て上記のコードを実行しようと私の経験に基づいて、常にラウンドアップに> * 0.5が必要な場合には、実際にMidpointRounding.AwayFromZeroをしたいmsdn.microsoft.com/en-us/library/...
イライジャ・ロフグレン

@ElijahLofgren状況によって異なります。統計を行っている場合ToEvenは、統計のドリフトを防ぐ必要があります。ただし、課金対象のアイテムまたはお金で操作する場合はAwayFromZero、正しい選択のようです。
mbx 2018

22
decimal d = 2;
int i = (int) d;

これは問題なく動作するはずです。


注意して、明示的な変換情報が失われる可能性があります。
パイドロス

21
10進数からintに変換すると、ほとんどの場合情報が失われますが、それがちょっと重要だと思います。
ダイナ


8

System.DecimalメンバーIConvertableを持つインターフェースを実装しますToInt32()

電話は効きSystem.Decimal.ToInt32()ますか?


2
ドキュメントから:「このAPIは.NET Frameworkインフラストラクチャをサポートし、コードから直接使用するためのものではありません」。Convert.ToInt32を使用しないのはなぜですか?
H.Wolper、2015

7

高速丸めの巧妙なトリックは、小数をintにキャストする前に.5を追加することです。

decimal d = 10.1m;
d += .5m;
int i = (int)d;

まだ去りますi=10

decimal d = 10.5m;
d += .5m;
int i = (int)d;

そのように切り上げるでしょうi=11


5
Math.FloorとMath.Ceilingがあるのに、なぜこれを行う必要があるのでしょうか。
Badaro、

当時、私はC#を初めて使用したことがあり、何らかの理由でこれらの関数が存在することに気付きませんでした。これは実際にはC / C ++から学んだトリックであり、明らかにより有用でした。
DeadlyBrad42 09/09/26

1
10進値がたとえば-9.3の場合はどうなりますか?
スーパーキャット2014年

6

私が使用して好む恐らくMath.roundMath.FloorMath.CeilingまたはMath.Truncateを必要に応じて明示的に設定丸めモードに。

それらはすべてDecimalも返すことに注意してください。DecimalはInt32よりも値の範囲が広いため、キャスト(およびオーバーフロー/アンダーフローをチェック)する必要があります。

 checked {
   int i = (int)Math.Floor(d);
 }


6

小数を最も近い整数に丸める

decimal a ;
int b = (int)(a + 0.5m);

ときa = 49.9、その後、b = 50

ときa = 49.5、その後、b = 50

いつa = 49.4b = 49など


0

ボックス化された10進数(つまり、オブジェクトタイプ内の10進数値)がある場合、キャスト演算子が機能しないことがわかりました。この場合、Convert.ToInt32(decimal as object)は正常に機能します。

この状況は、データベースからIDENTITY / AUTONUMBER値を取得するときに発生します。

SqlCommand foo = new SqlCommand("INSERT INTO...; SELECT SCOPE_IDENTITY()", conn);
int ID = Convert.ToInt32(foo.ExecuteScalar());  // works
int ID = (int)foo.ExecuteScalar();              // throws InvalidCastException

4.3.2変換のボックス化解除を参照してください


2
参照用にさらに追加します。これは、同じ元のタイプにしかボックスを解除できないためです。ここでSELECT SCOPE_IDENTITY()リターンnumeric(38, 0)に変換decimal.NETで。foo.ExecuteScalar()に直接キャストできないdecimalボックス化を返します。または動作します。objectint(int)(decimal)foo.ExecuteScalar()Convert.ToInt32(foo.ExecuteScalar())
レイジット2014年

0

intの範囲外の10進数を変換しようとすることから生じるOverflowException / UnderflowExceptionを処理するための答えはないようです。

int intValue = (int)Math.Max(int.MinValue, Math.Min(int.MaxValue, decimalValue));

このソリューションは、10進値がintの範囲外の場合、可能な最大または最小のint値を返します。値がint範囲内にある場合は、Math.Round、Math.Ceiling、またはMath.Floorを使用して丸めを追加することができます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.