Mengapa ada begitu banyak tipe numerik (bit, int, float, double, long)?

9

Saya telah belajar PHP, Java, dan C. Sekarang saya ingin tahu mengapa ada begitu banyak jenis tipe data numerik seperti bit, int, float, double, dan panjang. Mengapa tidak membuat hanya satu jenis untuk numerik?

Apakah ada manfaatnya? Mungkin jika kita menggunakan bilangan bulat untuk menampung angka sekecil itu, kita bisa menghemat memori?

GusDeCooL
sumber
6
Selain jawaban HorusKol: tipe 'float' dan 'integer' pada dasarnya berbeda. Mengapung dapat menampung angka yang sangat besar, tetapi saat ukuran angkanya naik, presisi menurun. Ketidaktepatan ini karena cara pelampung disimpan. Sebaliknya, rentang nilai yang dapat Anda simpan dalam bilangan bulat cukup terbatas, tetapi nilainya selalu tepat, sehingga Anda dapat membandingkan nilai lebih mudah. Juga, ada dua jenis perilaku dengan pembagian - bilangan bulat 'terpotong' ke seluruh nomor terdekat secara otomatis, mengapung tidak. Masing-masing perilaku ini berguna untuk situasi yang berbeda.
kampu
Javascript hanya memiliki satu tipe angka di permukaan.
Esailija
@kampu: Sebenarnya, dalam banyak bahasa, integer dapat menyimpan angka apa pun selama memori (virtual) cukup besar untuk mewakilinya.
Jörg W Mittag
1
@ JörgWMittag: Namun, penanya itu jelas berbicara tentang bahasa statis, bukan bahasa dinamis seperti Python, misalnya. CPython sendiri mengimplementasikan integer 'jangkauan tak terbatas' sebagai larik int 32-bit, dengan bit terakhir pada setiap int digunakan untuk menunjukkan apakah ada lebih banyak bit yang tersisa. Juga, bilangan bulat dapat menyimpan seluruh nomor saja. Itu berarti bahwa pelampung dengan penyimpanan tanpa batas dapat menyimpan nilai ke presisi (infinity aleph one), sementara bilangan bulat dapat menyimpan nilai hanya untuk presisi ( infinity aleph nol ).
kampu
@kampu: Karena semua angka diwakili oleh serangkaian bit, bahkan dengan penyimpanan tak terbatas, akan selalu ada pemetaan satu-ke-satu antara angka floating point dan bilangan bulat. Jadi saya tidak berpikir aleph yang perlu dipertanyakan.
DATANG DARI

Jawaban:

17

Ada dua alasan mengapa Anda harus peduli dengan tipe data numerik yang berbeda.

1. Menyimpan memori

for(long k=0;k<=10;k++)
{
    //stuff
}

Mengapa menggunakan lama ketika bisa dengan mudah menjadi bilangan bulat, atau bahkan byte? Anda memang akan menghemat beberapa byte memori dengan melakukannya.

2. Angka titik mengambang dan angka integer disimpan secara berbeda di komputer

Misalkan kita memiliki nomor 22 yang disimpan dalam bilangan bulat. Komputer menyimpan nomor ini dalam memori dalam biner sebagai:

0000 0000 0000 0000 0000 0000 0001 0110

Jika Anda tidak terbiasa dengan sistem bilangan biner ini dapat direpresentasikan dalam notasi ilmiah sebagai: 2 ^ 0 * 0 + 2 ^ 1 * 1 + 2 ^ 2 * 1 + 2 ^ 3 * 0 + 2 ^ 4 * 1 + 2 ^ 5 * 0 + ... + 2 ^ 30 * 0. Bit terakhir mungkin atau mungkin tidak digunakan untuk menunjukkan apakah angka itu negatif (tergantung jika tipe data ditandatangani atau tidak ditandatangani).

Pada dasarnya, ini hanya penjumlahan dari nilai 2 ^ (bit place) *.

Ini berubah ketika Anda merujuk ke nilai yang melibatkan titik desimal. Misalkan Anda memiliki angka 3,75 dalam desimal. Ini disebut sebagai 11.11 dalam biner. Kita dapat menyatakan ini sebagai notasi ilmiah sebagai 2 ^ 1 * 1 + 2 ^ 0 * 1 + 2 ^ -1 * 1 + 2 ^ -2 * 1 atau, dinormalisasi, sebagai 1.111 * 2 ^ 2

Namun komputer tidak dapat menyimpannya: ia tidak memiliki metode eksplisit untuk mengekspresikan titik biner tersebut (versi sistem angka biner dari titik desimal). Komputer hanya dapat menyimpan angka 1 dan angka 0. Di sinilah tipe data floating point masuk.

Dengan asumsi sizeof (float) adalah 4 byte, maka Anda memiliki total 32 bit. Bit pertama diberi "bit tanda". Tidak ada pelampung tanpa tanda tangan atau ganda. 8 bit berikutnya digunakan untuk "eksponen" dan 23 bit terakhir digunakan sebagai "signifand" (atau kadang-kadang disebut sebagai mantissa). Menggunakan contoh 3,75 kami, eksponen kami adalah 2 ^ 1 dan signifikansi kami adalah 1,111.

Jika bit pertama adalah 1, angkanya negatif. Jika tidak, positif. Eksponen dimodifikasi oleh sesuatu yang disebut "bias", jadi kita tidak bisa hanya menyimpan "0000 0010" sebagai eksponen. Bias untuk angka floating point presisi tunggal adalah 127, dan bias untuk presisi ganda (di sinilah tipe data ganda mendapatkan namanya) adalah 1023. 23 bit terakhir dicadangkan untuk signifikansi. Signifikansi hanyalah nilai-nilai HAK dari titik biner kami.

Eksponen kami akan menjadi bias (127) + eksponen (1) atau diwakili dalam biner

1000 0000

Signifikan kami adalah:

111 0000 0000 0000 0000 0000

Oleh karena itu, 3,75 direpresentasikan sebagai:

0100 0000 0111 0000 0000 0000 0000 0000

Sekarang, mari kita lihat angka 8 yang direpresentasikan sebagai angka floating point dan sebagai angka integer:

0100 0001 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 1000

Bagaimana di dunia ini komputer akan menambahkan 8.0 dan 8? Atau bahkan melipatgandakannya !? Komputer (lebih khusus, komputer x86) memiliki bagian-bagian berbeda dari CPU yang menambahkan angka floating point dan angka integer.

cpmjr123
sumber
3
3) walaupun jarang menjadi masalah: Operasi pada angka yang lebih besar dari ukuran kata komputer lebih lambat.
Loren Pechtel
6

Kembali sebelum kami memiliki sistem gigabyte (atau pada sistem embedded modern seperti Arduino), memori berada pada tingkat yang lebih tinggi sehingga metode singkatan diterapkan untuk menentukan berapa banyak memori yang akan diambil oleh angka tertentu - BIT mudah - awalnya hanya menempati 1 bit memori.

Ukuran dan nama data lainnya bervariasi di antara sistem. Pada sistem 32-bit, INT (atau MEDIUMINT) umumnya akan menjadi 2 byte, LONGINT akan menjadi 4 byte, dan SMALLINT akan menjadi satu byte. Sistem 64-bit dapat mengatur LONGINT pada 8-byte.

Bahkan sekarang - terutama dalam aplikasi basis data, atau program yang memiliki banyak kejadian berjalan di server (seperti skrip sisi server di situs web) - Anda harus berhati-hati tentang apa yang Anda pilih. Memilih integer lebar 2, 4, atau 8 byte untuk menyimpan nilai antara 0 dan 100 (yang dapat ditampung dalam satu byte) sangat boros jika Anda memiliki tabel database dengan jutaan catatan.

Informasi lebih lanjut: https://en.wikipedia.org/wiki/Integer_(computer_science)

HorusKol
sumber
jawaban bagus +1.
Vinay
7
Tidak hanya 'kembali sebelum', tetapi juga 'sekarang ketika suatu sistem kecil'. Pada perangkat ukuran Arduino harus ekonomis.
9000
1
Sistem apa yang digunakan hanya 1 bit untuk menyimpan sedikit? bit biasanya tidak langsung dialamatkan
jk.
1
itu benar dalam banyak arsitektur - tetapi bit secara langsung dapat dialamatkan dalam sistem yang benar-benar tua, dan bahkan beberapa sistem tertanam yang lebih baru (beberapa pengendali yang saya programkan hanya 10 tahun yang lalu bekerja dengan bit - yang hanya memiliki sekitar 64 lokasi yang dapat dialamatkan dengan lebar tertentu). Saat ini, saya kira kompiler mengerjakannya dan memasukkannya ke dalam byte-array.
HorusKol
Saya pikir faktor utama adalah kemampuan dan kinerja CPU daripada masalah memori
James
4

Selain poin cpmjr123 yang sangat baik tentang kelangkaan memori dan ketepatan dan rentang trade off, ada juga potensi CPU trade off.

Sebagian besar mesin modern memiliki perangkat keras khusus untuk melakukan operasi floating point yang disebut FPU. Ada juga sistem yang tidak memiliki FPU's (saat ini ini biasanya perangkat embeded kecil), akibatnya, tergantung pada perangkat keras target Anda, Anda harus tidak menggunakan jenis titik mengambang sama sekali atau menggunakan perangkat lunak perpustakaan titik mengambang. Bahkan jika mesin Anda memiliki FPU, secara historis ada perbedaan dalam fungsi apa yang bisa diberikannya. Setiap fungsi yang tidak dilakukan dalam perangkat keras harus dilakukan dalam perangkat lunak (atau dihindari)

Melakukan perhitungan floating point dalam perangkat lunak dilakukan dengan melakukan banyak operasi sederhana yang didukung perangkat keras. Karena itu, Anda juga mendapatkan potensi trade off yang cepat.

jk.
sumber
4

Mungkin yang paling penting adalah bahwa sebenarnya ada tiga tipe angka dasar yang berbeda.

bilangan bulat, desimal tetap dan titik mengambang.

Mereka semua berperilaku berbeda.

Operasi sederhana seperti 7/2 dapat memberikan jawaban 3, 3,50 dan 3,499 tergantung pada tipe data yang digunakan.

"fixed desimal" adalah jenis Cinderella, hanya didukung secara asli dalam beberapa bahasa seperti COBOL dan VisualBasic. Ini sedikit menarik bagi para ilmuwan komputer tetapi sangat penting bagi siapa pun yang mengirimkan satu set akun atau menghitung pajak penjualan pada suatu faktur.

James Anderson
sumber
Saya akan memisahkan mereka secara berbeda: angka diskrit, angka perkiraan, dan pembungkus cincin aljabar. Contoh umum di C akan int, floatdan unsigned int, masing-masing. Tipe fixed-point adalah subkategori tipe diskrit, tetapi cincin aljabar secara fundamental berbeda dari angka [harus dari kebingungan mengenai tipe unsigned di C berasal dari fakta bahwa mereka kebanyakan berperilaku seperti cincin daripada angka, tetapi tidak cukup konsisten] .
supercat
3

Apakah ada manfaatnya?

Tentu saja. Ada manfaatnya. Dalam dunia komputer, memori adalah salah satu hal terpenting yang harus dipertimbangkan. Apa gunanya memiliki memori 2kb ketika data bisa muat kurang dari 1kb? . Optimasi harus ada di sana. Jika Anda menggunakan lebih banyak memori, itu jelas membunuh kecepatan komputer Anda pada suatu titik. Apakah Anda benar-benar suka memilikinya? Tidak benar ...?

int - 2 bytes (16 bits)

long - 4 bytes (32 bits)

long long - 8 bytes (64 bits)

float - 4 bytes

Tidak hanya memori tetapi ada organisasi jenis angka juga. misalnya floating point. Presisi sangat penting dan jelas kita harus memiliki satu jenis yang dapat memberi kita lebih banyak presisi.

Jika kami mempertimbangkan masa lalu, kami memiliki memori yang sangat sedikit seperti yang Anda tahu. Untuk menyimpannya dan menggunakannya dengan bijak, kami memiliki perbedaan ini. Dan masih banyak lagi jika Anda langsung saja mencoba melakukan pencarian dengan google .. Semoga ini bisa membantu.

Vinay
sumber
3

bilangan bulat dan bilangan real (float, double) adalah tipe yang berbeda secara konseptual dengan rangkaian operasi dan properti intrinsik yang berbeda.

Bilangan bulat dapat dihitung tetapi float tidak, dll.

Sebenarnya Float / angka ganda adalah struktur yang menggabungkan dua bidang bilangan bulat: mantissa dan eksponen. Bilangan kompleks (yang dikecualikan dari pertimbangan Anda) bahkan lebih kompleks.

Setiap bahasa praktis harus memiliki setidaknya bilangan bulat dan mengapung sebagai tipe yang berbeda - operasi yang terlalu berbeda.

c-senyum
sumber
Saya tidak terbiasa dengan "bilangan kompleks" yang Anda sebutkan. Bisakah Anda jelaskan lebih lanjut?
cpmjr123
Saya mengetahui bilangan kompleks dalam bentuk a + bi. Saya meminta informasi lebih lanjut tentang bagaimana komputer menyimpan bilangan kompleks. Setahu saya, tidak ada tipe data primitif yang mendukung ini.
cpmjr123
Bilangan kompleks biasanya disimpan sebagai dua nilai floating point, yaitu a(bagian nyata) dan b(bagian imajiner). CPU biasanya tidak mengimplementasikan dukungan asli untuk operasi pada bilangan kompleks, meskipun CPU dapat menerapkan instruksi tambah-tambah yang dipercepat untuk operasi pada pasangan nilai, seperti (a + c d) dan (a b-c d).
rwong
1
Selain itu, banyak bahasa memiliki beberapa jenis yang perilakunya sebagian besar didefinisikan sebagai cincin aljabar pembungkus (misalnya jika variabel jenis uint16_tmemegang 65535, jika ditambahkan maka akan membuatnya tahan 0). Idealnya, bahasa memiliki tipe yang terpisah untuk merepresentasikan cincin dan angka aljabar yang membungkus (memungkinkan angka yang meluap terperangkap, sementara memungkinkan kode untuk dengan mudah melakukan operasi pada hal-hal yang diharapkan untuk dibungkus).
supercat
-1

Selain fakta bahwa tipe floating-point berperilaku sangat berbeda dari tipe integer, saya ingin memberikan contoh yang lebih ekstrim mengapa ukuran per angka sangat penting.

Bayangkan Anda ingin mengurutkan array (panjang). Misalnya dalam C:

int numbers[100000000];

Jadi di sini kita memiliki 100 juta angka.

Jika setiap angka hanya satu byte panjang (jadi unsigned charalih-alih menggunakan int), maka ini membutuhkan 100 Juta byte ruang.

Jika Anda menggunakan double, maka ini biasanya 8 byte per angka, jadi 800 Juta byte ruang.

Jadi setiap kali Anda beroperasi dengan banyak objek (angka dalam contoh ini), ukuran per objek (ukuran per nomor dalam contoh ini) benar-benar penting.

Ingo Blackman
sumber