Mengapa Math.Floor (Double) mengembalikan nilai bertipe Double?


103

Saya perlu mendapatkan nilai integer sisi kiri dari desimal atau ganda. Untuk Contoh: Saya perlu mendapatkan nilai 4 dari 4.6. Saya mencoba menggunakan fungsi Math.Floor tetapi mengembalikan nilai ganda, misalnya: Ini mengembalikan 4.0 dari 4.6. Dokumentasi MSDN mengatakan bahwa ia mengembalikan nilai integer. Apakah saya melewatkan sesuatu di sini? Atau adakah cara lain untuk mencapai apa yang saya cari?


2
Dokumentasi MSDN mengatakan bahwa ia mengembalikan nilai integer . Dokumentasi MSDN menyatakan bahwa Math.Floor mengembalikan System.Double, bukan integer.
broadband

Nilai integer dibutuhkan secara efektif, tetapi tidak berarti bahwa itu dapat disimpan dalam "int" atau "long". Sebuah "ganda" berhasil menyimpan semua nilai integer dalam rentang yang jauh lebih luas daripada hanya "int" Perhatikan bahwa beberapa nilai integer mungkin dibulatkan ketika bagian mantissa tidak memiliki cukup bit untuk menyimpan semua digit nilai integer, ketika eksponen basis-2-nya berjalan di atas 52: pembulatan nilai integer dalam "double" dapat terjadi untuk bilangan bulat di atas 2 ^ 52 atau di bawah -2 ^ 52 tetapi hasilnya akan tetap mewakili bilangan bulat terdekat; jika Anda menggunakan "(panjang) Lantai (x)", konversinya mungkin sebagian besar salah.
verdy_p

Namun perlu diperhatikan bahwa kisaran valid dari integer vallues yang dapat direpresentasikan dalam "double" sangatlah besar, dengan nilai absolut hingga: (1 + (1 - 2 ^ −52)) × 2 ^ 1023 ≈ 1.7976931348623157E308; ini lebih dari 2 ^ 63-1 dengan "long". Namun kisaran bilangan bulat yang semuanya dapat disimpan dengan jelas lebih terbatas, karena "ganda" hanya memiliki 52 bit untuk mantissa (ditambah 1 bit tersirat untuk bit yang paling signifikan, tidak disimpan), yang berarti bahwa "ganda" hanya dapat menyimpan bilangan bulat tepat hanya jika nilai absolutnya di bawah 2 ^ 53.
verdy_p

Sayangnya, Math.Floor () tidak mengembalikan tipe variabel "Number" secara internal menggunakan "Long" jika memungkinkan, atau "Double" sebaliknya hanya untuk integer bulat besar. Dan pustaka matematika standar tidak menangani tipe nomor variabel terpadu seperti itu. Terdapat pustaka matematika lain yang menerapkan tipe bilangan terpadu, termasuk bilangan bulat panjang, ganda, atau besar yang dikodekan dalam desimal atau biner yang dikemas tanpa kehilangan rentang atau presisi yang didukung.
verdy_p

Jawaban:


146

Rentangnya doublejauh lebih lebar daripada rentang intatau long. Pertimbangkan kode ini:

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

Bilangan bulat berada di luar kisaran long- jadi apa yang Anda harapkan terjadi?

Biasanya Anda tahu bahwa nilai sebenarnya akan berada dalam kisaran intatau long, jadi Anda melemparkannya:

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

namun tanggung jawab untuk pemeran tersebut ada pada pengembang, bukan pada Math.Floordirinya sendiri. Ini akan menjadi pembatasan yang tidak perlu untuk membuatnya gagal dengan pengecualian untuk semua nilai di luar rentang long.


2
Lantai mengembalikan representasi bilangan bulat ganda, dan mengembalikan ganda untuk perhitungan ilmiah, jawaban ini tidak benar karena ganda memiliki 64 bit dan panjang juga memiliki 64 bit, tetapi ganda tidak dapat menyimpan digit tepat dari bit signifikan yang lebih rendah meskipun dapat disimpan dengan benar dalam waktu lama.
Akash Kava

1
@ Jon: kenapa Anda belum mempertimbangkan perdebatan yang berkecamuk tentang bagaimana membuat bilangan positif menjadi negatif di C # ?: stackoverflow.com/questions/1348080/…
MusiGenesis

3
@ Jon: luangkan waktu Anda. Ternyata masyarakat menemukan bahwa mengalikan bilangan positif dengan -1 akan menjadikannya negatif. Semuanya baik-baik saja di StackOverflow.
MusiGenesis

1
@javapowered: Tidak, (int) 15.0 bukan 0. Ada sesuatu yang salah, tapi kita tidak bisa membedakan apa dari itu. Harap buat program singkat tapi lengkap yang mendemonstrasikan ini, lalu ajukan pertanyaan. Saya kira Anda akan kesulitan untuk mereproduksi ...
Jon Skeet

1
@MusiGenesis: <code> (int) IGNORE_RATIO * Volume </code> dihitung sebagai <code> (int) 0,15 * Volume </code>, tetapi typecast hanya berlaku untuk rasio, bukan hasil produk, dan Anda mendapatkan <code> 0 * Volume </code> yaitu nol! Gunakan <code> (int) (IGNORE_RATIO * Volume) </code> sebagai gantinya untuk mengatasi bug ANDA.
verdy_p

11

Menurut MSDN, Math.Floor (double) mengembalikan ganda: http://msdn.microsoft.com/en-us/library/e0b5f0xb.aspx

Jika Anda menginginkannya sebagai int:

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

Saya dapat melihat bagaimana artikel MSDN dapat menyesatkan, mereka seharusnya menetapkan bahwa meskipun hasilnya adalah "integer" (dalam hal ini berarti bilangan bulat), artikel tersebut tetap TYPE Double


Terimakasih atas balasan anda. Sebenarnya saya sedang melihat artikel ini: msdn.microsoft.com/en-us/library/e0b5f0xb.aspx Tapi bagaimanapun, saya akan mencoba saran Anda. Terima kasih.

Memang benar, itu mengatakan di bagian atas "mengembalikan integer" tetapi jenisnya ditentukan di bawahnya: public static double Floor (double d)
Neil N

3
integer! = int( Answers.com/integer ) - bilangan bulat dapat disimpan di Double(lihat jawaban Jon), dan ada bilangan bulat yang tak terbatas yang tidak dapat disimpan di int.
Shog9

Shog, aku tidak bilang mereka tidak bisa. Apa yang saya katakan adalah "masih dari TIPE Ganda"
Neil N

1
@Neil: benar - hanya ingin menekankan perbedaan antara "integer" (nama set) dan int(nama jenis).
Shog9

4

Jika Anda hanya membutuhkan bagian bilangan bulat dari sebuah angka, masukkan angka tersebut menjadi int. Ini akan memotong angka di titik desimal.

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

2
Penting untuk diperhatikan bahwa casting intberperilaku berbeda Floor, untuk bilangan negatif. Floorakan selalu dipotong ke angka paling negatif, sedangkan casting ke intakan dipotong ke 0.
Magnus


0

Lantai meninggalkannya sebagai ganda sehingga Anda dapat melakukan lebih banyak perhitungan ganda dengannya. Jika Anda menginginkannya sebagai int, gunakan hasil floor sebagai int. Jangan gunakan dobel asli sebagai int karena aturan untuk lantai berbeda (IIRC) untuk bilangan negatif.


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

Ini akan memberi Anda nilai yang tepat apa yang Anda inginkan seperti jika Anda mengambil 4.6itu kembali 4sebagai output.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.