Mengambang dan menggandakan datatype di Jawa

220

Tipe data float adalah floating point IEEE 754 32-bit presisi tunggal dan tipe data ganda adalah floating point IEEE 754 64-bit presisi ganda.

Apa artinya? Dan kapan saya harus menggunakan float bukan double atau sebaliknya?

Leo
sumber
8
Anda harus menggunakan float bukannya double ketika penggunaan memori sangat penting. Jika Anda membutuhkan perhitungan yang lebih tepat, gunakan ganda.
Everv0id
12
@ Everv0id: Saya tidak yakin dengan situasi di mana ingatannya sangat ketat sehingga harus mengorbankan akurasi untuk ruang. (Anda menggunakan Java , demi kebaikan ...) Mungkin ada beberapa situasi ketika itu dipanggil, tetapi dalam praktik saya, saya jarang melihatnya. Jika Anda ingin menguraikan mengapa Anda percaya ini adalah ide yang bagus, memberikan jawaban dengan contoh misalnya akan menjadi tambahan yang layak.
Makoto
5
@ Makoto sebenarnya, saya tidak pernah menggunakan pelampung, hanya ganda. Tetapi mungkin ada aplikasi (secara teori) yang harus menyimpan sejumlah besar angka floating point, sehingga penggunaan memori 2x bisa menjadi kritis. Secara teori, ofc; dalam praktiknya Anda selalu dapat membeli server lain .
Everv0id
3
Saya telah menggunakan 4 byte dan bahkan 2 byte angka presisi tetap untuk menghemat memori, tetapi kecuali jika Anda memiliki miliaran dari ini, itu tidak akan sepadan. Waktu yang Anda perlukan untuk menulis "dobel" bukan "mengambang" (memiliki satu huruf lagi) bernilai 1000x lebih banyak daripada memori ekstra yang Anda gunakan, tetapi jika menggunakan doubledaripada floatmenyelamatkan Anda dari bug terkait presisi, sia-sia .
Peter Lawrey

Jawaban:

259

The Wikipedia halaman pada itu adalah tempat yang baik untuk memulai.

Untuk menyimpulkan:

  • floatdiwakili dalam 32 bit, dengan 1 bit tanda, 8 bit eksponen, dan 23 bit signifikan (atau yang mengikuti dari angka notasi ilmiah: 2.33728 * 10 12 ; 33728 adalah signifikan).

  • double direpresentasikan dalam 64 bit, dengan 1 bit tanda, 11 bit eksponen, dan 52 bit signifikan.

Secara default, Java menggunakan doubleuntuk mewakili angka floating-point (jadi literal 3.14diketik double). Ini juga tipe data yang akan memberi Anda rentang angka yang jauh lebih besar, jadi saya akan sangat menyarankan penggunaannya berakhir float.

Mungkin ada perpustakaan tertentu yang benar-benar memaksa penggunaan Anda float, tetapi secara umum - kecuali jika Anda dapat menjamin bahwa hasil Anda akan cukup kecil untuk muat di float's kisaran yang ditentukan , maka yang terbaik untuk opt dengan double.

Jika Anda membutuhkan akurasi - misalnya, Anda tidak dapat memiliki nilai desimal yang tidak akurat (seperti 1/10 + 2/10), atau Anda melakukan apa pun dengan mata uang (misalnya, mewakili $ 10,33 dalam sistem), kemudian gunakan a BigDecimal, yang dapat mendukung jumlah presisi yang sewenang-wenang dan menangani situasi seperti itu dengan elegan.

Makoto
sumber
4
Bukankah 233728 == mantissa dalam contoh yang diberikan? Maksud saya, di mana lagi bagian integer disimpan?
JaLoveAst1k
1
@ mathguy54: Dalam notasi ilmiah, 2 akan menjadi bilangan bulat keseluruhan dan 0,33728 akan menjadi mantissa. Ini referensi untuk itu.
Makoto
5
Saya sedang mencari info tentang float dan double dan menemukan ini dan perlu berkomentar: jika Anda melakukan sesuatu dengan mata uang yang tidak melibatkan sen pecahan, menggunakan BigDecimal itu konyol. Mata uang umum adalah data diskrit, jadi Anda harus menggunakan tipe data integer. (Ini adalah salah satu kesalahan yang lebih umum dilakukan oleh programmer muda - karena kami menggunakan a. Untuk memisahkan dolar dari sen, mereka pikir itu nilai floating point. Tidak.)
Trixie Wolf
2
@TrixieWolf, bisakah Anda lebih spesifik, apakah Anda mengusulkan untuk menggunakan dua bilangan bulat (integer dan bagian desimal)? Dan Anda berbicara tentang mata uang umum, bagaimana dengan sisanya? Beberapa jumlah dievaluasi dengan 6 desimal sehingga Anda tidak bisa begitu saja *100. Tolong, Anda ada benarnya di sini, tetapi bisakah Anda lebih tepat :)
AxelH
9
@AxelH Kecuali untuk bagian tengah perhitungan keuangan di mana sen pecahan bisa ada, uang selalu diskrit. Anda akan menggunakan satu tipe integer untuk menyimpan data. Jadi $ 5,34 akan disimpan sebagai 534. Bagian dolar adalah val / 100 dalam matematika bilangan bulat, dan sen adalah val% 100 dalam matematika bilangan bulat, di mana% mengacu pada operasi sisanya. Untuk uang dengan lebih banyak tempat yang melewati desimal, harus tetap disimpan sebagai integral karena terpisah. Bahkan jika itu tidak diskrit, seringkali Anda ingin mundur ke penyimpanan diskrit karena itu tepat sehingga Anda tidak akan kehilangan uang karena kesalahan pembulatan.
Trixie Wolf
72

Float memberi Anda kira-kira. 6-7 presisi angka desimal sementara ganda memberi Anda kira-kira. 15-16. Juga kisaran angka lebih besar untuk ganda.

Double membutuhkan ruang penyimpanan 8 byte sementara float hanya membutuhkan 4 byte.

Henry
sumber
13

Bilangan floating-point, juga dikenal sebagai bilangan real, digunakan ketika mengevaluasi ekspresi yang membutuhkan ketelitian fraksional. Misalnya, perhitungan seperti akar kuadrat, atau transendental seperti sinus dan kosinus, menghasilkan nilai yang ketelitiannya membutuhkan tipe titik-mengambang. Java mengimplementasikan set tipe dan operator floatingpoint (IEEE – 754) standar. Ada dua jenis tipe floating-point, float dan double, yang masing-masing mewakili angka presisi tunggal dan ganda. Lebar dan rentangnya ditampilkan di sini:


   Name     Width in Bits   Range 
    double  64              1 .7e308 to 1.7e+308
    float   32              3 .4e038 to 3.4e+038


mengapung

Tipe float menentukan nilai presisi tunggal yang menggunakan 32 bit penyimpanan. Presisi tunggal lebih cepat pada beberapa prosesor dan membutuhkan ruang setengah dari presisi ganda, tetapi akan menjadi tidak tepat ketika nilainya sangat besar atau sangat kecil. Variabel tipe float berguna ketika Anda membutuhkan komponen fraksional, tetapi tidak memerlukan tingkat presisi yang besar.

Berikut adalah beberapa contoh deklarasi variabel float:

mengapung hightemp, lowtemp;


dua kali lipat

Presisi ganda, sebagaimana dilambangkan dengan kata kunci ganda, menggunakan 64 bit untuk menyimpan nilai. Presisi ganda sebenarnya lebih cepat daripada presisi tunggal pada beberapa prosesor modern yang telah dioptimalkan untuk perhitungan matematika berkecepatan tinggi. Semua fungsi matematika transendental, seperti sin (), cos (), dan sqrt (), mengembalikan nilai ganda. Ketika Anda perlu menjaga akurasi dari banyak perhitungan berulang, atau memanipulasi angka bernilai besar, double adalah pilihan terbaik.

Kamu Menang
sumber
Jawaban ini jelas diklarifikasi kapan kita harus menggunakan float dan double. Mengapa tidak?
Ye Win
8
Baik jenis floatmaupun doubleyang terbaik digunakan untuk mata uang di Jawa, karena mereka membuka peluang untuk kesalahan pembulatan. Artikel ini membahas lebih detail: javapractices.com/topic/TopicAction.do?Id=13
PPartisan
1
"Pelampung bisa bermanfaat ketika mewakili dolar dan sen." - tidak tidak tidak tidak tidak tidak tidak. Jangan pernah menyimpan mata uang sebagai pelampung / ganda.
mengurangi aktivitas
2

Meskipun demikian, Java tampaknya memiliki bias terhadap penggunaan ganda untuk perhitungan:

Contohnya program yang saya tulis sebelumnya hari ini, metode tidak bekerja ketika saya menggunakan float, tapi sekarang berfungsi dengan baik ketika saya mengganti float dengan double (dalam NetBeans IDE):

package palettedos;
import java.util.*;

class Palettedos{
    private static Scanner Z = new Scanner(System.in);
    public static final double pi = 3.142;

    public static void main(String[]args){
        Palettedos A = new Palettedos();
        System.out.println("Enter the base and height of the triangle respectively");
        int base = Z.nextInt();
        int height = Z.nextInt();
        System.out.println("Enter the radius of the circle");
        int radius = Z.nextInt();
        System.out.println("Enter the length of the square");
        long length = Z.nextInt();
        double tArea = A.calculateArea(base, height);
        double cArea = A.calculateArea(radius);
        long sqArea = A.calculateArea(length);
        System.out.println("The area of the triangle is\t" + tArea);
        System.out.println("The area of the circle is\t" + cArea);
        System.out.println("The area of the square is\t" + sqArea);
    }

    double calculateArea(int base, int height){
        double triArea = 0.5*base*height;
        return triArea;
    }

    double calculateArea(int radius){
        double circArea = pi*radius*radius;
        return circArea;
    }

    long calculateArea(long length){
        long squaArea = length*length;
        return squaArea;
    }
}
Raymond Wachaga
sumber
Saya memiliki masalah yang sama hari ini. Apa yang bisa menjadi alasan di balik bias ini?
Shachi
2

Ini akan memberikan kesalahan:

public class MyClass {
    public static void main(String args[]) {
        float a = 0.5;
    }
}

/MyClass.java:3: error: tipe yang tidak kompatibel: kemungkinan konversi lossy dari float ganda menjadi float a = 0,5;

Ini akan bekerja dengan baik

public class MyClass {
    public static void main(String args[]) {
        double a = 0.5;
    }
}

Ini juga akan berfungsi dengan baik

public class MyClass {
    public static void main(String args[]) {
        float a = (float)0.5;
    }
}

Alasan : Java secara default menyimpan bilangan real sebagai ganda untuk memastikan presisi yang lebih tinggi.

Double membutuhkan lebih banyak ruang tetapi lebih presisi selama komputasi dan float membutuhkan lebih sedikit ruang tetapi kurang tepat.

Himanshu Singh
sumber
1

Menurut standar IEEE, float adalah representasi 32 bit dari bilangan real sedangkan ganda adalah representasi 64 bit.

Dalam program Java biasanya kita sebagian besar melihat penggunaan tipe data ganda. Hanya untuk menghindari luapan karena rentang angka yang dapat ditampung menggunakan tipe data ganda lebih banyak daripada rentang ketika float digunakan.

Juga ketika presisi tinggi diperlukan, penggunaan ganda dianjurkan. Beberapa metode perpustakaan yang diimplementasikan sejak lama masih membutuhkan penggunaan tipe data float sebagai suatu keharusan (itu hanya karena diimplementasikan menggunakan float, tidak ada yang lain!).

Tetapi jika Anda yakin bahwa program Anda membutuhkan jumlah kecil dan meluap tidak akan terjadi dengan penggunaan float Anda, maka penggunaan float sebagian besar akan meningkatkan kompleksitas ruang Anda karena float membutuhkan setengah memori seperti yang diperlukan oleh ganda.

Rubal
sumber
0

Contoh ini menggambarkan cara mengekstrak tanda (bit paling kiri), eksponen (8 bit berikut) dan mantissa (23 bit paling kanan) dari float di Jawa.

int bits = Float.floatToIntBits(-0.005f);
int sign = bits >>> 31;
int exp = (bits >>> 23 & ((1 << 8) - 1)) - ((1 << 7) - 1);
int mantissa = bits & ((1 << 23) - 1);
System.out.println(sign + " " + exp + " " + mantissa + " " +
  Float.intBitsToFloat((sign << 31) | (exp + ((1 << 7) - 1)) << 23 | mantissa));

Pendekatan yang sama dapat digunakan untuk mantissa ganda (eksponen 11 bit dan 52 bit).

long bits = Double.doubleToLongBits(-0.005);
long sign = bits >>> 63;
long exp = (bits >>> 52 & ((1 << 11) - 1)) - ((1 << 10) - 1);
long mantissa = bits & ((1L << 52) - 1);
System.out.println(sign + " " + exp + " " + mantissa + " " +
  Double.longBitsToDouble((sign << 63) | (exp + ((1 << 10) - 1)) << 52 | mantissa));

Kredit: http://sj.github.io/java-float/

acohen
sumber
0

Anda harus menggunakan double bukannya float untuk perhitungan yang tepat, dan float bukannya double ketika menggunakan perhitungan yang kurang akurat. Float hanya berisi angka desimal, tetapi ganda mengandung nomor floating point presisi IEEE754, membuatnya lebih mudah untuk memuat dan menghitung angka lebih akurat. Semoga ini membantu.

boi yeet
sumber
0

Dalam perhitungan pemrograman reguler, kami tidak menggunakan float. Jika kami memastikan bahwa kisaran hasil berada dalam kisaran tipe data float, maka kami dapat memilih tipe data float untuk menghemat memori. Secara umum, kami menggunakan ganda karena dua alasan: -

  • Jika kita ingin menggunakan angka floating-point sebagai tipe data float maka pemanggil metode harus secara eksplisit memberikan akhiran F atau f, karena secara default setiap angka floating-point diperlakukan sebagai dobel. Ini menambah beban bagi programmer. Jika kita menggunakan angka floating-point sebagai tipe data ganda maka kita tidak perlu menambahkan akhiran apa pun.
  • Float adalah tipe data presisi tunggal yang berarti ia menempati 4 byte. Karenanya dalam perhitungan besar, kami tidak akan mendapatkan hasil yang lengkap. Jika kita memilih tipe data ganda, ini menempati 8 byte dan kita akan mendapatkan hasil yang lengkap.

Tipe float dan double data dirancang khusus untuk perhitungan ilmiah, di mana kesalahan aproksimasi dapat diterima. Jika keakuratan menjadi perhatian utama, maka disarankan untuk menggunakan kelas BigDecimal daripada tipe data float atau double. Sumber: - Mengambang dan menggandakan tipe data di Jawa

Rocco Jerry
sumber