Anda tampaknya memiliki gagasan yang tidak akurat tentang apa itu mantissa dan eksponen. Mereka bukan hanya "seluruh bagian" dan "bagian pecahan". Lihat en.wikipedia.org/wiki/Floating_point
Jon Skeet
Sebenarnya saya membaca sekitar 5 posting sebelum berkata 'hei .. itu tidak disebut eksponen'. Otak saya membuang kata-kata dan mulai memecahkan masalah .. kebiasaan buruk membaca hal-hal pemrograman telah memberi saya :)
Gishu
1
Juga harap susun ulang pertanyaan OP .. untuk anak cucu di antara alasan-alasan lain.
Gishu
1
Kedengarannya seperti masalah pekerjaan rumah yang mencurigakan.
Brian Knoblauch
ohh begitu. saya sudah bertanya-tanya bagaimana dia mendapatkan hasil yang begitu aneh
double num;long iPart;double fPart;// Get user input
num =2.3d;
iPart =(long) num;
fPart = num - iPart;System.out.println("Integer part = "+ iPart);System.out.println("Fractional part = "+ fPart);
Keluaran:
Integer part =2Fractional part =0.2999999999999998
Sebenarnya halaman ini adalah hit pertama pada pencarian google untuk "get fractional and whole part out from double java" =)
Chris
12
Sebenarnya jawaban ini salah, karena nilai yang lebih besar dari panjang dapat mewakili maka akan memberikan angka yang sangat besar pada bagian pecahannya. Jawaban Dan Vinton di bawah ini sesederhana itu dan selalu mengembalikan hasil yang benar.
arberg
2
jadi sebenarnya, ini tidak benar, seperti yang Anda lihat di output. masukannya adalah pecahan dari 3 dan keluarannya adalah 29999999 ... menggunakan BigDecimal daripada Double akan melakukan triknya
Alex
2
@Alex Tidak, inputnya adalah angka yang sangat dekat dengan 2.3, tapi pasti tidak 2.3. Dan tidak ada yang salah dengan hasilnya, kecuali jika Anda menginginkan lebih dari 10 digit yang valid. Yang Anda butuhkan hanyalah beberapa pembulatan di setiap keluaran (misalnya, format %.9f) yang biasanya tidak terlalu merepotkan BigDecimal. Satu-satunya masalah di sini adalah overflow.
maaartinus
1
Mengubah double menjadi int hampir selalu merupakan ide yang buruk. Karena misalnya untuk (long)1.0e100Anda akan mendapatkan 0. Seringkali Anda membutuhkan nilai ganda hanya "berlantai" yang ada floor(). Jika Anda ingin menggunakan bagian integral dan pecahan modf(). Sungguh, ini jawaban yang buruk.
mojuba
155
double value =3.25;double fractionalPart = value %1;double integralPart = value - fractionalPart;
Mengapa ini tidak disukai? Bekerja dengan baik, dan dengan pengeditan saya akan bekerja dengan nilai-nilai negatif juga.
HRJ
Bagian integer bisa => long longPart = (long) 3.25
jdurango
2
Tidak akan berhasil untuk neg. nilai-nilai. Yaitu -3,25% 1 = 0,75 bukan 0,25. Jadi integralPart akan menjadi -3,25 - 0,75 = -4.
WindRider
2
@WindRider, saya cek negatif .. dan berhasil .. namun untuk tempat desimal yang jumlahnya kecil, akan ada sedikit kesalahan. Ex. untuk -03.0025 mengembalikan -0.0024999999999999467 dan -3.0
justshams
5
Kebingungan di sini adalah karena beberapa bahasa, seperti Python, digunakan %untuk berarti modulo ( -3.25 % 1 == 0.75) dan lainnya, seperti Java, Fortran, C, dan C ++, digunakan %untuk mengartikan sisa ( -3.25 % 1 == -0.25). WindRider mungkin telah mengetikkannya ke dalam REPL Python untuk kepentingannya, tetapi jawaban itu menyesatkan karena pertanyaan ini tentang JVM.
Jim Pivarski
24
Karena pertanyaan berusia 1 tahun ini ditendang oleh seseorang yang mengoreksi subjek pertanyaan, dan pertanyaan ini telah diberi tag jsp, dan tidak ada orang di sini yang dapat memberikan jawaban yang ditargetkan JSP, inilah kontribusi saya yang ditargetkan untuk JSP.
Gunakan JSTL (cukup taruh jstl-1.2.jar di /WEB-INF/lib) fmt taglib. Ada <fmt:formatNumber>tag yang melakukan apa yang Anda inginkan dan dengan cara yang cukup mudah dengan bantuan maxFractionDigitsdan maxIntegerDigitsatribut.
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%><%// Just for quick prototyping. Don't do this in real! Use servlet/javabean.double d =3.25;
request.setAttribute("d", d);%><!doctype html><html lang="en"><head><title>SO question 343584</title></head><body><p>Whole:<fmt:formatNumber value="${d}" maxFractionDigits="0"/><p>Fraction:<fmt:formatNumber value="${d}" maxIntegerDigits="0"/></body></html>
Keluaran:
Seluruh: 3
Pecahan: .25
Itu dia. Tidak perlu memijatnya dengan bantuan kode Java mentah.
Bukankah bit pertama mantinssa secara implisit diatur ke 1, jadi mantissa harus (bits & 0x000fffffffffffffL) | 0x0010000000000000L?
agnul
Rasmus itu bukan keluaran ryt Output: eksponen 0 dan mantissa 2814749767106560 dan jika Anda memilih kami agnul mantissa adalah 0
Vinayak Bevinakatti
Rusak dengan 4 suara lebih :) Meskipun saya melihat apa yang kode coba lakukan dengan memisahkan nilai ganda pada sambungannya, kode tersebut tampaknya tidak menghasilkan nilai yang benar.
Gishu
@agnul: Saya pikir "mantissa" biasanya hanya mengacu pada nilai bit. Anda mungkin hanya mengubahnya menjadi signifikan dengan (kadang-kadang) prepending sedikit. Namun menurut Wikipedia, kata mantissa sekarang sudah tidak digunakan lagi dan diganti dengan "pecahan".
Rasmus Faber
5
Logika utama Anda harus terlebih dahulu menemukan berapa digit yang ada setelah koma desimal.
Kode ini berfungsi untuk nomor apa pun hingga 16 digit. Jika Anda menggunakan BigDecimal, Anda dapat menjalankannya hingga 18 digit. letakkan nilai input (nomor Anda) ke variabel "num", di sini sebagai contoh saya telah mengodekannya dengan keras.
Sobat, ini adalah jawaban yang sangat rumit untuk masalah sederhana. Apakah Anda melihat jawaban yang diterima?
Abu
1
Sekarang orang yang melakukan down-vote (bukan saya btw), seharusnya menjelaskan kenapa ada down-vote. Itu tidak baik. Tetapi kita semua memiliki skor 1 di beberapa titik atau lainnya.
Abu
2
@Gray pertanyaannya adalah memisahkan 3,25 sebagai '3' dan '25', dan jawaban yang diterima tidak akan pernah memberikan '25', itu akan selalu memberikan '2599999999'
OnePunchMan
@Gray Saya tahu siapa yang downvote itu, itu adalah nama pria Eji (pengguna lama) yang mengejek setiap komentar, jawaban, dan pertanyaan saya yang saya posting di blog ini. Akhirnya saya komplain ke moderator.
OnePunchMan
2
Jawaban ini sangat berguna jika Anda menginginkan bagian pecahan sebagai bilangan bulat
Guilherme Campos Hazan
5
Mantissa dan eksponen dari bilangan floating point ganda IEEE adalah nilai yang sedemikian rupa
value = sign *(1+ mantissa)* pow(2, exponent)
jika mantissa berbentuk 0.101010101_base 2 (yaitu bit yang paling signifikan digeser menjadi setelah titik biner) dan eksponen disesuaikan untuk bias.
Sejak 1.6, java.lang.Math juga menyediakan metode langsung untuk mendapatkan eksponen yang tidak bias (disebut getExponent (double))
Namun, bilangan yang Anda minta adalah bagian integral dan pecahan dari bilangan tersebut, yang dapat diperoleh dengan menggunakan
integral =Math.floor(x)
fractional = x -Math.floor(x)
meskipun Anda mungkin ingin memperlakukan angka negatif secara berbeda (floor(-3.5) == -4.0) , tergantung mengapa Anda menginginkan kedua bagian tersebut.
Saya sangat menyarankan agar Anda tidak menyebut mantissa dan eksponen ini.
Bagian bilangan bulat didapat dari pengecoran sederhana dan untuk pecahan - pemisahan string:
double value =123.004567890int integerPart =(int) value;// 123int fractionPart =Integer.valueOf(String.valueOf(value).split(".")[1]);// 004567890/**
* To control zeroes omitted from start after parsing.
*/int decimals =String.valueOf(value).split(".")[1].length();// 9
Karena fmt:formatNumbertag tidak selalu memberikan hasil yang benar, berikut adalah pendekatan khusus JSP lainnya: Ini hanya memformat angka sebagai string dan melakukan penghitungan lainnya pada string, karena itu lebih mudah dan tidak melibatkan floating point lebih lanjut aritmatika.
Coba saja semua angka dari contoh saya. fmt:formatNumbermembulatkan argumennya, yang tidak diinginkan dalam kasus ini.
Roland Illig
0
Banyak dari jawaban ini memiliki kesalahan pembulatan yang mengerikan karena mereka mentransmisikan angka dari satu jenis ke jenis lainnya. Bagaimana tentang:
Jawaban yang diterima tidak berfungsi dengan baik untuk bilangan negatif antara -0 dan -1.0 Berikan juga bagian pecahannya negatif.
Contoh: Untuk angka -0,35
kembali
Bagian bilangan bulat = 0 Bagian pecahan = -0.35
Jika Anda bekerja dengan koordinat GPS, lebih baik mendapatkan hasil dengan signum pada bagian integer sebagai:
Bagian bilangan bulat = -0 Bagian pecahan = 0.35
Angka-angka ini digunakan misalnya untuk koordinat GPS, dimana penting signum untuk posisi Lat atau Long
Usulkan kode:
double num;double iPart;double fPart;// Get user input
num =-0.35d;
iPart =(long) num;//Correct numbers between -0.0 and -1.0
iPart =(num<=-0.0000001&& num>-1.0)?-iPart : iPart ;
fPart =Math.abs(num - iPart);System.out.println(String.format("Integer part = %01.0f",iPart));System.out.println(String.format("Fractional part = %01.04f",fPart));
Saya akan menggunakan BigDecimal untuk solusinya. Seperti ini:
double value =3.25;BigDecimal wholeValue =BigDecimal.valueOf(value).setScale(0,BigDecimal.ROUND_DOWN);double fractionalValue = value - wholeValue.doubleValue();
Jawaban ini telah ditandai sebagai kualitas rendah. Jika itu menjawab pertanyaan, pertimbangkan untuk menambahkan sedikit teks untuk menjelaskan cara kerjanya.
lmo
0
// target float point numberdouble d =3.025;// transfer the number to stringDecimalFormat df =newDecimalFormat();
df.setDecimalSeparatorAlwaysShown(false);String format = df.format(d);// split the number into two fragmentsint dotIndex = format.indexOf(".");int iPart =Integer.parseInt(format.substring(0, dotIndex));// output: 3double fPart =Double.parseDouble(format.substring(dotIndex));// output: 0.025
Jika Anda memiliki ganda, itu memiliki ketidaktepatan float. Mengonversinya menjadi BigDecimal tidak akan mengembalikan ketepatannya secara ajaib.
Taschi
@Taschi saya pikir pertanyaannya adalah tentang memisahkan bagian int dan pecahan, bukan tentang mengembalikan presisi!
Omar Elashry
Omar, Anda secara khusus berbicara tentang pendekatan Anda yang "lebih akurat", yang menurut saya tidak benar. Jawaban Anda sepenuhnya dapat diterima tetapi kata-kata itu tampaknya menyesatkan bagi saya, itulah sebabnya saya mengomentarinya.
Taschi
@Taschi, saya mengatakan bahwa karena dalam banyak jawaban Anda kehilangan nilai ketika Anda mendapatkan output, misalnya input (5.03)output int = 5 , fractional = 0.0299999, kita berbicara tentang input dan output, Anda memberi nilai dan mendapatkan kembali nilai Anda tanpa kehilangan 0,001% darinya! dan ini akurat, tidak menyesatkan!
Omar Elashry
Iya. Anda kehilangan presisi saat menyimpan sesuatu sebagai dobel di tempat pertama. Pembulatan saat mengonversi ke BigDecimal juga kehilangan presisi. Kedua kehilangan presisi tersebut dapat saling meniadakan, tetapi itu tidak "memulihkan" presisi, karena pemulihan presisi secara matematis tidak mungkin. Anda tidak dapat menarik informasi begitu saja.
Jawaban:
http://www.java2s.com/Code/Java/Data-Type/Obtainingtheintegerandfractionalparts.htm
Keluaran:
sumber
2.3
, tapi pasti tidak2.3
. Dan tidak ada yang salah dengan hasilnya, kecuali jika Anda menginginkan lebih dari 10 digit yang valid. Yang Anda butuhkan hanyalah beberapa pembulatan di setiap keluaran (misalnya, format%.9f
) yang biasanya tidak terlalu merepotkanBigDecimal
. Satu-satunya masalah di sini adalah overflow.(long)1.0e100
Anda akan mendapatkan 0. Seringkali Anda membutuhkan nilai ganda hanya "berlantai" yang adafloor()
. Jika Anda ingin menggunakan bagian integral dan pecahanmodf()
. Sungguh, ini jawaban yang buruk.sumber
%
untuk berarti modulo (-3.25 % 1 == 0.75
) dan lainnya, seperti Java, Fortran, C, dan C ++, digunakan%
untuk mengartikan sisa (-3.25 % 1 == -0.25
). WindRider mungkin telah mengetikkannya ke dalam REPL Python untuk kepentingannya, tetapi jawaban itu menyesatkan karena pertanyaan ini tentang JVM.Karena pertanyaan berusia 1 tahun ini ditendang oleh seseorang yang mengoreksi subjek pertanyaan, dan pertanyaan ini telah diberi tag jsp, dan tidak ada orang di sini yang dapat memberikan jawaban yang ditargetkan JSP, inilah kontribusi saya yang ditargetkan untuk JSP.
Gunakan JSTL (cukup taruh jstl-1.2.jar di
/WEB-INF/lib
) fmt taglib. Ada<fmt:formatNumber>
tag yang melakukan apa yang Anda inginkan dan dengan cara yang cukup mudah dengan bantuanmaxFractionDigits
danmaxIntegerDigits
atribut.Ini SSCCE , cukup copy'n'paste'n'run itu.
Keluaran:
Itu dia. Tidak perlu memijatnya dengan bantuan kode Java mentah.
sumber
Pertanyaan awal menanyakan eksponen dan mantissa, bukan pecahan dan seluruh bagian.
Untuk mendapatkan eksponen dan mantissa dari double, Anda dapat mengubahnya menjadi representasi IEEE 754 dan mengekstrak bit seperti ini:
sumber
Logika utama Anda harus terlebih dahulu menemukan berapa digit yang ada setelah koma desimal.
Kode ini berfungsi untuk nomor apa pun hingga 16 digit. Jika Anda menggunakan BigDecimal, Anda dapat menjalankannya hingga 18 digit. letakkan nilai input (nomor Anda) ke variabel "num", di sini sebagai contoh saya telah mengodekannya dengan keras.
sumber
Mantissa dan eksponen dari bilangan floating point ganda IEEE adalah nilai yang sedemikian rupa
jika mantissa berbentuk 0.101010101_base 2 (yaitu bit yang paling signifikan digeser menjadi setelah titik biner) dan eksponen disesuaikan untuk bias.
Sejak 1.6, java.lang.Math juga menyediakan metode langsung untuk mendapatkan eksponen yang tidak bias (disebut getExponent (double))
Namun, bilangan yang Anda minta adalah bagian integral dan pecahan dari bilangan tersebut, yang dapat diperoleh dengan menggunakan
meskipun Anda mungkin ingin memperlakukan angka negatif secara berbeda
(floor(-3.5) == -4.0)
, tergantung mengapa Anda menginginkan kedua bagian tersebut.Saya sangat menyarankan agar Anda tidak menyebut mantissa dan eksponen ini.
sumber
Tidak tahu apakah ini lebih cepat tetapi saya menggunakan
sumber
[Sunting: Pertanyaan awalnya menanyakan bagaimana mendapatkan mantissa dan eksponen.]
Di mana n adalah angka untuk mendapatkan mantissa / eksponen nyata:
Atau, untuk mendapatkan jawaban yang Anda cari:
Ini sebenarnya bukan Java tetapi harus mudah dikonversi.
sumber
Bagian bilangan bulat didapat dari pengecoran sederhana dan untuk pecahan - pemisahan string:
sumber
Bagaimana jika nomor Anda adalah 2.39999999999999. Saya kira Anda ingin mendapatkan nilai desimal yang tepat. Kemudian gunakan BigDecimal:
sumber
Karena
fmt:formatNumber
tag tidak selalu memberikan hasil yang benar, berikut adalah pendekatan khusus JSP lainnya: Ini hanya memformat angka sebagai string dan melakukan penghitungan lainnya pada string, karena itu lebih mudah dan tidak melibatkan floating point lebih lanjut aritmatika.sumber
fmt:formatNumber
membulatkan argumennya, yang tidak diinginkan dalam kasus ini.Banyak dari jawaban ini memiliki kesalahan pembulatan yang mengerikan karena mereka mentransmisikan angka dari satu jenis ke jenis lainnya. Bagaimana tentang:
sumber
Math.abs
?Jawaban yang diterima tidak berfungsi dengan baik untuk bilangan negatif antara -0 dan -1.0 Berikan juga bagian pecahannya negatif.
Contoh: Untuk angka -0,35
kembali
Bagian bilangan bulat = 0 Bagian pecahan = -0.35
Jika Anda bekerja dengan koordinat GPS, lebih baik mendapatkan hasil dengan signum pada bagian integer sebagai:
Bagian bilangan bulat = -0 Bagian pecahan = 0.35
Angka-angka ini digunakan misalnya untuk koordinat GPS, dimana penting signum untuk posisi Lat atau Long
Usulkan kode:
Keluaran:
sumber
Sejak Java 8, Anda dapat menggunakan
Math.floorDiv
.Ini mengembalikan nilai terbesar (terdekat dengan tak terhingga positif)
int
yang kurang dari atau sama dengan hasil bagi aljabar.Beberapa contoh:
Alternatifnya,
/
operator dapat digunakan:Referensi:
sumber
Saya akan menggunakan BigDecimal untuk solusinya. Seperti ini:
sumber
sumber
sumber
Oke, ini mungkin terlambat, tetapi menurut saya pendekatan terbaik dan lebih akurat adalah menggunakan BigDecimal
sumber
input (5.03)
output int = 5 , fractional = 0.0299999
, kita berbicara tentang input dan output, Anda memberi nilai dan mendapatkan kembali nilai Anda tanpa kehilangan 0,001% darinya! dan ini akurat, tidak menyesatkan!sumber