Math.Floor(Double)がDouble型の値を返すのはなぜですか?


103

10進数またはdoubleから左側の整数値を取得する必要があります。例:4.6から値4を取得する必要があります。Math.Floor関数を使用してみましたが、例としてdouble値が返されます。4.6から4.0が返されます。MSDNドキュメントは、整数値を返すと言います。ここで何か不足していますか?または私が探しているものを達成する別の方法はありますか?


2
MSDNのドキュメントには、整数値が返されると記載されていますMSDNのドキュメントでは、Math.Floorは整数ではなくSystem.Doubleを返すと述べています。
ブロードバンド

整数は事実上必要ですが、それが「int」または「long」に格納できることを意味するものではありません。「double」は、すべての整数値を単に「int」よりもはるかに広い範囲に正常に格納します。仮数部に整数値のすべての桁を格納するのに十分なビットがない場合、一部の整数値は丸められる場合があります。 52を超える:この「double」の整数値の丸めは、2 ^ 52を超える、または-2 ^ 52を下回る整数で発生する可能性がありますが、結果は表現可能な最も近い整数になります。"(long)Floor(x)"を使用すると、変換が大幅に失敗する可能性があります。
verdy_p

ただし、「double」で表すことができる整数値の有効範囲は非常に大きく、絶対値は(1 +(1 − 2 ^ −52))×2 ^ 1023≈1.7976931348623157E308です。"long"の場合は2 ^ 63-1をはるかに超えています。ただし、「double」は仮数に52ビットしかない(プラス1ビットは最上位ビットを意味し、保存されない)ため、すべてを明確に保存できる整数の範囲はより制限されます。整数は、絶対値が2 ^ 53未満の場合にのみ正確にoonlyになります。
verdy_p

残念ながら、Math.Floor()は、可能であれば "Long"を内部的に使用して変数 "Number"型を返さず、それ以外の場合は大きな丸め整数に対してのみ "Double"を返しません。また、標準の数学ライブラリは、このような統一された変数型を処理しません。サポートされている範囲や精度を失うことなく、パック10進数または2進数でエンコードされた長整数、倍長整数、長整数など、統一された数値型を実装する他の数学ライブラリが存在します。
verdy_p

回答:


146

範囲は、doubleの範囲よりもはるかに広いですintlong。このコードを考えてみましょう:

double d = 100000000000000000000d;
long x = Math.Floor(d); // Invalid in reality

整数が範囲外ですlong-何が起こると思いますか?

通常は、値がされますことを知って、実際の範囲内にあることintlong、あなたがそれを唱えるので、:

double d = 1000.1234d;
int x = (int) Math.Floor(d);

しかし、そのキャストの責任はMath.Floorそれ自体ではなく開発者にあります。の範囲外のすべての値を例外として、失敗するだけでは不必要に制限的でしたlong


2
Floorはdoubleの整数表現を返し、科学計算ではdoubleを返します。doubleは64ビットでlongも64ビットであるため、この答えは正しくありませんが、doubleは、正しく格納できても、下位ビットの正確な桁を格納できません。長い間。
Akash Kava、

1
@ジョン:どのようにあなたがC#?:正の数負の作り方を超える荒れ狂う議論にで計量していない来stackoverflow.com/questions/1348080/...
MusiGenesis

3
@ジョン:あなたの時間をかけてください。コミュニティは、正の数に-1を掛けると負になることを発見しました。StackOverflowは順調です。
MusiGenesis 2009

1
@javapowered:いいえ、(INT)15.0はない何か他のものがなくなって間違っを持っていますが、我々はちょうどそれから何を言うことができない0。これを示す短い完全なプログラムを作成してから、質問してください。再現するのは難しいと思います...
ジョン・スキート

1
@MusiGenesis:<code>(int)IGNORE_RATIO * Volume </ code>は<code>(int)0.15 * Volume </ code>として計算されますが、型キャストは比率にのみ適用され、製品の結果には適用されません。 <code> 0 * Volume </ code>、つまりゼロを取得します。代わりに<code>(int)(IGNORE_RATIO * Volume)</ code>を使用してバグを解決してください。
verdy_p

11

MSDNによると、(ダブル)Math.Floorはダブルを返します。http://msdn.microsoft.com/en-us/library/e0b5f0xb.aspx

あなたがそれをintとして望むなら:

int result = (int)Math.Floor(yourVariable);

私は、MSDNの記事が誤解を招く可能性があることを確認できますが、結果は「整数」(この場合は整数)であるが、それでもTYPE Doubleであると彼らは指定しているはずです


お返事ありがとうございます。実際、私はこの記事を見ていました: msdn.microsoft.com/en-us/library/e0b5f0xb.aspx とにかく、私はあなたの提案を試みます。ありがとうございました。

確かに、それは「整数を返す」とは言っていますが、タイプはその下で指定されています。public static double Floor(double d)
Neil N

3
integer!= intanswers.com/integer)-整数に格納できDouble(Jonの回答を参照)、に格納できない整数は無限にありintます。
Shog9 2009

Shog、私は彼らができないとは言っていない。私が言ったことは「それはまだTYPE Doubleです」
Neil N

1
@ニール:正しい-「整数」(セットのint名前)と(タイプの名前)の違いを強調したかっただけです。
Shog9 2009

4

数値の整数部分だけが必要な場合は、数値をにキャストしintます。これにより、小数点以下が切り捨てられます。

double myDouble = 4.6;
int myInteger = (int)myDouble;

2
負の数の場合、intへのキャストはとは異なる動作をすることに注意してくださいFloorFloorいつもにキャストするのに対し、最も負の数に切り捨てますint0に向けて切り捨てられます
マグナス


0

Floorはdoubleのままにするため、それを使用してdoubleの計算をさらに実行できます。intとして必要な場合は、floorの結果をintとしてキャストします。負の数の場合、フロアのルールが異なるため(IIRC)、元のdoubleをintとしてキャストしないでください。


0
Convert.ToInt32(Math.Floor(Convert.ToDouble(value)))

これにより、出力として4.6返す場合に必要な正確な値が得4られます。

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