Neden bu kadar çok sayısal tür var (bit, int, float, double, long)?


9

PHP, Java ve C'yi öğrendim. Şimdi neden bit, int, float, double ve long gibi birçok sayısal veri türü olduğunu merak ediyorum. Neden nümerikler için sadece bir tür yapmıyorsunuz?

Bunun bir yararı var mı? Belki bu kadar küçük sayıları tutmak için tamsayılar kullanırsak hafızadan tasarruf edebiliriz?


6
HorusKol'un cevabına ek olarak: 'float' ve 'integer' tipleri doğal olarak farklıdır. Şamandıralar çok büyük sayılar tutabilir, ancak sayının boyutu arttıkça hassasiyet düşer. Bu kesinsizlik şamandıraların depolanma biçiminden kaynaklanmaktadır. Buna karşılık, bir tamsayıda saklayabileceğiniz değer aralığı oldukça sınırlıdır, ancak değer her zaman doğrudur, böylece değerleri daha kolay karşılaştırabilirsiniz. Ayrıca, bölme ile iki farklı davranış türü vardır - tamsayı otomatik olarak en yakın tam sayıya 'keser', yüzer. Bu davranışların her biri farklı durumlar için yararlıdır.
kampu

Javascript, yüzeyde sadece bir sayı tipine sahiptir.
Esailija

@kampu: Aslında, birçok dilde, (sanal) bellek onu temsil edecek kadar büyük olduğu sürece tamsayılar herhangi bir sayıyı saklayabilir.
Jörg W Mittag

1
@ JörgWMittag: Ancak, bu soru soran, açıkça Python gibi dinamik dillerden değil, statik dillerden bahsediyor. CPython 'sınırsız aralık' tamsayısını 32 bitlik bir dizi olarak uygular ve her int'deki son bit, daha fazla bit olup olmadığını göstermek için kullanılır. Ayrıca, tamsayılar herhangi bir tam sayıyı saklayabilir . Bu, sonsuz depolamalı bir şamandıra, değerleri hassasiyete (sonsuz aleph bir) kaydedebilirken, tamsayılar değerleri yalnızca hassasiyete ( sonsuz aleph sıfır ) depolayabilir .
kampu

@kampu: Tüm sayılar sonsuz depolama ile bile bir dizi bit ile temsil edildiğinden, kayan nokta sayıları ve tamsayılar arasında her zaman bire bir eşleme olacaktır. Bu yüzden aleph'in sorgulamaya geldiğini sanmıyorum.
GELMEKTEDİR

Yanıtlar:


17

Farklı sayısal veri türleriyle ilgilenmeniz için iki neden vardır.

1. Bellek tasarrufu

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

Neden bir tamsayı, hatta bir bayt olabildiğince uzun bir süre kullanılsın? Gerçekten bunu yaparak birkaç bayt bellek tasarruf edersiniz.

2. Kayan nokta sayıları ve tamsayı sayıları bilgisayarda farklı şekilde saklanır

Diyelim ki 22 tamsayıda kayıtlı. Bilgisayar bu sayıyı ikili olarak belleğe kaydeder:

0000 0000 0000 0000 0000 0000 0001 0110

İkili sayı sistemine aşina değilseniz, bilimsel gösterimde şu şekilde temsil edilebilir: 2 ^ 0 * 0 + 2 ^ 1 * 1 + 2 ^ 2 * 1 + 2 ^ 3 * 0 + 2 ^ 4 * 1 + 2 ^ 5 * 0 + ... + 2 ^ 30 * 0. Son bit, sayının negatif olup olmadığını belirtmek için kullanılabilir veya kullanılamaz (veri türünün imzalı veya imzasız olmasına bağlı olarak).

Temelde, sadece 2 ^ (bit yeri) * değerinin bir toplamıdır.

Ondalık basamak içeren değerlere başvurduğunuzda bu durum değişir. Ondalık sayı olarak 3.75'in olduğunu varsayalım. Buna ikili dosyada 11.11 denir. Bunu bilimsel bir gösterim olarak 2 ^ 1 * 1 + 2 ^ 0 * 1 + 2 ^ -1 * 1 + 2 ^ -2 * 1 veya normalleştirilmiş olarak 1.111 * 2 ^ 2 olarak gösterebiliriz.

Ancak bilgisayar bunu saklayamaz: Bu ikili noktayı (ondalık noktanın ikili sayı sistemi sürümü) ifade etmek için açık bir yöntemi yoktur. Bilgisayar yalnızca 1'leri ve 0'ları depolayabilir. Kayan nokta veri türü burada devreye girer.

Sizeof (float) boyutunun 4 bayt olduğunu varsayarsak, toplam 32 bitiniz vardır. İlk bite "işaret biti" atanır. İmzasız şamandıra veya çiftler yoktur. Sonraki 8 bit "üs" için kullanılır ve son 23 bit "anlamlı" olarak kullanılır (veya bazen mantis olarak da adlandırılır). 3.75 örneğimizi kullanarak üsümüz 2 ^ 1 ve önemimiz 1.111 olacaktır.

İlk bit 1 ise sayı negatif olur. Değilse, olumlu. Üs, "sapma" adı verilen bir şeyle değiştirildiğinden, "0000 0010" u üs olarak saklayamayız. Tek duyarlıklı kayar nokta sayısı için sapma 127'dir ve çift duyarlıklı sapma (çift veri tipinin adını aldığı yer) 1023'tür. Son 23 bit anlamlılık için ayrılmıştır. Önemli olan, sadece ikili noktamızın SAĞ değerindeki değerlerdir.

Üsümüz önyargı (127) + üs (1) veya ikili olarak temsil edilir

1000 0000

Bizim amacımız:

111 0000 0000 0000 0000 0000

Bu nedenle, 3.75 şu şekilde temsil edilir:

0100 0000 0111 0000 0000 0000 0000 0000

Şimdi kayan nokta sayısı ve tam sayı olarak temsil edilen 8 rakamına bakalım:

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

Bilgisayar nasıl 8.0 ve 8 ekleyecek? Ya da onları çarpın !? Bilgisayar (daha spesifik olarak x86 bilgisayarlar) CPU'nun kayan nokta sayıları ve tamsayı sayıları ekleyen farklı bölümlerine sahiptir.


3
3) nadir de olsa bir sorun: Bilgisayarın kelime boyutundan daha büyük sayılardaki işlemler daha yavaştır.
Loren Pechtel

6

Gigabayt sistemlerimiz olmadan önce (veya Arduino gibi modern gömülü sistemlerde), bellek birinci sınıftaydı ve bu nedenle belirli bir sayının ne kadar bellek alacağını belirlemek için kısayol yöntemleri uygulandı - BIT basittir - başlangıçta sadece 1 bit kaplardı bellek.

Diğer veri boyutları ve adları sistemler arasında farklılık gösterir. 32 bitlik bir sistemde, INT (veya MEDIUMINT) genellikle 2 bayt, LONGINT 4 bayt ve SMALLINT tek bayt olur. 64 bit sistemler LONGINT'i 8 bayt olarak ayarlayabilir.

Şimdi bile - özellikle veritabanlarındaki uygulamalarda veya sunucularda çalışan birden çok örneği olan programlarda (web sitelerindeki sunucu tarafı komut dosyaları gibi) - ne seçtiğinize dikkat etmelisiniz. Milyonlarca kayıt içeren bir veritabanı tablonuz varsa, 0 ile 100 arasındaki değerleri depolamak için 2, 4 veya 8 bayt genişliğinde bir tamsayı seçmek (bir bayta sığabilecek) inanılmaz derecede israftır.

Daha fazla bilgi: https://en.wikipedia.org/wiki/Integer_(computer_science)


güzel cevap +1.
Vinay

7
Sadece 'önce' değil, aynı zamanda 'şimdi bir sistem küçükken'. Bir cihazda Arduino büyüklüğünün ekonomik olması gerekir.
9000

1
Hangi sistem biraz saklamak için sadece 1 bit kullandı? bit genellikle doğrudan adreslenemez
jk.

1
bu birçok mimaride doğrudur - ancak bitler gerçekten eski sistemlerde ve hatta daha yeni gömülü sistemlerde doğrudan ele alınabilirdi (sadece 10 yıl önce programladığım bazı kontrolörler bitlerle çalıştı - bunlar sadece belirli genişliklerde yaklaşık 64 adreslenebilir konuma sahipti). Bugünlerde, derleyiciler bunu çalıştırıyor ve bayt dizilerine koyuyorlar.
HorusKol

Bence en önemli faktör bellek kaygılarından ziyade CPU yeteneği ve performansı
James

4

Cpmjr123'ün bellek kıtlığı, hassasiyet ve menzil değişimleri ile ilgili mükemmel noktalarına ek olarak, bunlar potansiyel olarak bir CPU değiş tokuşudur.

Modern makinelerin çoğu, FPU adı verilen kayan nokta işlemlerini gerçekleştirmek için özel donanıma sahiptir. FPU'ları olmayan sistemler de vardır (günümüzde bunlar genellikle küçük gömülü aygıtlardır), dolayısıyla hedef donanımınıza bağlı olarak, kayan nokta türlerini kullanmanız veya bir yazılım kayan nokta kitaplığı kullanmanız gerekmeyecektir. Makinenizde bir FPU olsa bile, hangi işlevleri sağlayabileceği konusunda tarihsel olarak farklılıklar vardı. Donanımda yapılmayan tüm fonksiyonların yazılımda yapılması (veya kaçınılması) gerekir

Yazılımda kayan nokta hesaplamaları yapmak, donanımın desteklediği daha basit işlemler gerçekleştirilerek yapılır. Böylece potansiyel bir hızlı işlem yapıyorsunuz.


4

Belki de en önemli şey, gerçekten üç farklı temel sayı tipi olmasıdır.

tamsayı, sabit ondalık ve kayan nokta.

Hepsi farklı davranıyor.

7/2 gibi basit bir işlem, kullanılan veri türüne bağlı olarak 3, 3.50 ve 3.499 cevapları verebilir.

"sabit ondalık" Külkedisi türüdür, sadece COBOL ve VisualBasic gibi birkaç dilde desteklenmektedir. Bilgisayar bilimcileri için çok az ilgi çekicidir, ancak bir hesap kümesi gönderen veya bir faturada satış vergisi hesaplayan herkes için hayati önem taşır.


Onları farklı şekilde ayırırdım: ayrık sayılar, yaklaşık sayılar ve sarma cebir halkaları. C tipik örnekleri olur int, floatve unsigned intsırasıyla. Sabit noktalı türler ayrık türlerin bir alt kategorisidir, ancak cebirsel halkalar sayılardan temel olarak farklıdır [C'deki imzasız türlerle ilgili karışıklığın olması, sayılardan ziyade çoğunlukla halkalar gibi davrandıkları, ancak oldukça tutarlı olmadıkları gerçeğinden kaynaklanmaktadır ] .
supercat

3

Bunun yararları var mı?

Elbette. Faydaları var. Bilgisayar dünyasında bellek, göz önünde bulundurulması gereken en önemli şeylerden biridir. Veriler 1kb'den daha az sığabiliyorsa 2kb'lık bir belleğe sahip olmanın faydası nedir? . Optimizasyonlar orada olmalı. Daha fazla bellek kullanırsanız, belli bir noktada bilgisayarınızın hızını öldürür. Gerçekten sahip olmayı sever misin? Doğru değil...?

int - 2 bytes (16 bits)

long - 4 bytes (32 bits)

long long - 8 bytes (64 bits)

float - 4 bytes

Sadece hafıza değil, aynı zamanda sayıların organizasyonu da var. örnek kayan nokta için. Hassasiyet çok önemlidir ve açıkçası bize daha fazla hassasiyet verebilecek bir tipe sahip olmalıyız.

Eski günleri düşünürsek, bildiğiniz gibi çok daha az hafızamız vardı. Onu kurtarmak ve akıllıca kullanmak için bu farklılıklar vardı. Ve daha fazlası sadece devam edin ve google ile arama biraz deneyin .. Umarım bu yardımcı olur.


3

tamsayılar ve gerçek (float, double) sayılar, farklı işlem kümeleri ve iç özellikleri olan kavramsal olarak farklı türlerdir.

Tamsayılar numaralandırılabilir, ancak şamandıralar vb.

Aslında Float / double number iki tamsayı alanını birleştiren bir yapıdır: mantis ve üs. Karmaşık sayılar (dikkate aldığınız hariç) daha da karmaşıktır.

Herhangi bir pratik dil, en azından tamsayılara sahip olmalı ve farklı türler olarak yüzmelidir - bunlar üzerinde çok farklı işlemler.


Bahsettiğiniz "karmaşık sayılara" aşina değilim. Daha fazla açıklayabilir misiniz?
cpmjr123


A + bi biçimindeki karmaşık sayıların farkındayım. Bilgisayarın karmaşık sayıları nasıl sakladığı hakkında daha fazla bilgi istiyordum. Bildiğim kadarıyla, bunu destekleyen ilkel veri türleri yoktur.
cpmjr123

Karmaşık sayılar tipik olarak a(gerçek kısım) ve b(hayali kısım) olmak üzere iki kayan nokta değeri olarak saklanır . CPU tipik olarak karmaşık sayılardaki işlemler için yerel destek uygulamamaktadır, ancak CPU, (a b + c d) ve (a b-c d) gibi değer çiftlerindeki işlemler için hızlandırılmış çoklu ekleme talimatları uygulayabilir .
rwong

1
Ek olarak, birçok dilde davranışı büyük ölçüde bir sarma cebir halkasınınki gibi tanımlanır (örneğin, bir tür değişkeni uint16_t65535'i tutuyorsa, onu arttırırsa 0 tutacaktır). İdeal olarak, diller, sarma cebir halkalarını ve sayılarını temsil etmek için temiz bir şekilde ayrı tiplere sahip olacaktır ( taşan sayıların yakalanmasına izin verirken, kodun sarması beklenen şeyler üzerinde işlemleri kolayca gerçekleştirmesine izin verir ).
supercat

-1

Kayan nokta türlerinin tamsayı türlerinden tamamen farklı davrandığına ek olarak, sayı başına boyutun neden önemli olduğuna dair daha uç bir örnek vermek istiyorum.

Bir (uzun) dizi sıralamak istediğinizi düşünün. Örneğin C dilinde:

int numbers[100000000];

Burada 100 Milyon sayı var.

Her sayı yalnızca bir bayt uzunluğundaysa ( unsigned charbunun yerine kullanarak int), bunun için 100 Milyon bayt alan gerekir.

Kullanırsanız double, bu genellikle sayı başına 8 bayttır, bu nedenle 800 Milyon baytlık alan.

Bu nedenle , çok sayıda nesneyle (bu örnekteki sayılar) her çalıştığınızda , nesne başına boyut (bu örnekte sayı başına boyut) gerçekten önemlidir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.