Pertanyaan Mengapa Math.round mengembalikan panjang tetapi Math.floor mengembalikan dua kali lipat?


Mengapa inkonsistensi?


32
2017-08-05 07:06


asal


Jawaban:


Tidak ada ketidakkonsistenan: metode ini hanya dirancang untuk mengikuti spesifikasi yang berbeda.

Jadi berdasarkan desain round putaran ke a long dan rint putaran ke a double. Ini selalu terjadi sejak JDK 1.0.

Metode lain ditambahkan dalam JDK 1.2 (mis. toRadians, toDegrees); yang lain ditambahkan dalam 1,5 (mis. log10, ulp, signum, dll), namun beberapa ditambahkan dalam 1,6 (mis. copySign, getExponent, nextUp, dll) (cari file Sejak: metadata dalam dokumentasi); tapi round dan rint selalu memiliki satu sama lain dengan cara mereka sekarang sejak awal.

Bisa dibilang, mungkin bukan long round dan double rint, akan lebih "konsisten" untuk menamai mereka double round dan long rlong, tapi ini argumentatif. Yang mengatakan, jika Anda bersikeras secara kategoris menyebut ini sebagai "ketidakkonsistenan", maka alasannya mungkin tidak memuaskan seperti "karena tidak dapat dihindari".

Ini kutipan dari Java 2nd Edition efektif, Butir 40: Desain tanda tangan metode dengan hati-hati:

Jika ragu, lihat API perpustakaan Java untuk panduan. Meskipun ada banyak ketidakkonsistenan - tidak dapat dielakkan, mengingat ukuran dan ruang lingkup perpustakaan ini - ada juga sejumlah konsensus yang adil.

Pertanyaan-pertanyaan yang bertolak belakang


15
2017-08-05 07:57



floor akan dipilih untuk mencocokkan rutinitas c standar di math.h (rint, disebutkan dalam jawaban lain, juga hadir di perpustakaan itu, dan mengembalikan a double, seperti di java).

tapi round bukan fungsi standar dalam c pada waktu itu (tidak disebutkan dalam C89 - c identifier dan standar; c99 tidak mendefinisikan round dan mengembalikan a double, seperti yang Anda harapkan). itu normal bagi desainer bahasa untuk "meminjam" ide, jadi mungkin itu berasal dari bahasa lain? fortran 77 tidak memiliki fungsi nama itu dan saya tidak yakin apa lagi yang akan digunakan saat itu sebagai referensi. mungkin vb - yang memang ada Round tetapi, sayangnya untuk teori ini, ia mengembalikan a double (php juga). menariknya, perl sengaja menghindari mendefinisikan putaran.

[perbarui: hmmm. seperti smalltalk mengembalikan bilangan bulat. saya tidak cukup tahu tentang smalltalk untuk mengetahui apakah itu benar dan / atau umum, dan metode ini disebut rounded, tapi mungkin itu sumbernya. smalltalk memang mempengaruhi java dalam beberapa hal (meskipun lebih banyak konseptual daripada detail).]

jika tidak smalltalk, maka kita pergi dengan hipotesis bahwa seseorang hanya memilih buruk (diberikan konversi implisit mungkin di java tampaknya bagi saya bahwa mengembalikan doubleakan lebih berguna, sejak itu dapat digunakan baik ketika mengkonversi jenis dan ketika melakukan perhitungan floating point).

dengan kata lain: fungsi umum untuk java dan c cenderung konsisten dengan standar c library pada saat itu; sisanya tampak sewenang-wenang, tetapi kerutan khusus ini mungkin berasal dari smalltalk.


5
2018-03-17 04:18



Saya setuju, itu aneh sekali Math.round(double) kembali long. Jika besar double nilai-nilai dilemparkan ke long (yang adalah apa Math.round secara implisit), Long.MAX_VALUE dikembalikan. Sebuah alternatif sedang digunakan Math.rint() untuk menghindarinya. Namun, Math.rint() memiliki perilaku pembulatan yang agak aneh: ikatan diselesaikan dengan pembulatan ke bilangan bulat genap, yaitu 4.5 dibulatkan menjadi 4,0 tetapi 5,5 dibulatkan hingga 6,0). Alternatif lain adalah menggunakan Math.floor(x+0.5). Namun perlu diketahui bahwa 1,5 dibulatkan menjadi 2 sementara -1,5 dibulatkan menjadi -1, bukan -2. Namun alternatif lain adalah menggunakan Math.round, tetapi hanya jika nomor berada di rentang antara Long.MIN_VALUE dan Long.MAX_VALUE. Nilai presisi floating point ganda di luar rentang ini adalah bilangan bulat bagaimanapun juga.

Sayangnya, mengapa Math.round() kembali long tidak diketahui. Seseorang membuat keputusan itu, dan dia mungkin tidak pernah memberikan wawancara untuk memberi tahu kami alasannya. Tebakan saya adalah, Math.round itu dirancang untuk memberikan cara yang lebih baik (yaitu, dengan pembulatan) untuk mengkonversi ganda menjadi rindu.


1
2018-03-17 02:49