Ondalık sayılar neden tam olarak ikilik olarak gösterilemiyor?


284

Kayan nokta temsili hakkında SO'ya gönderilen çeşitli sorular vardır. Örneğin, ondalık sayı 0.1 tam bir ikili temsile sahip değildir, bu nedenle == işlecini başka bir kayan noktalı sayı ile karşılaştırmak tehlikelidir. Kayan nokta gösteriminin arkasındaki ilkeleri anlıyorum.

Anlamadığım şey, matematiksel bir perspektiften, ondalık noktanın sağındaki sayılar soldakilerden daha "özel" olan neden?

Örneğin, 61.0 sayısı tam bir ikili temsile sahiptir, çünkü herhangi bir sayının integral kısmı her zaman doğrudur. Ancak 6.10 sayısı tam değildir. Tek yaptığım ondalık bir yeri taşımaktı ve aniden Exactopia'dan Inexactville'e gittim. Matematiksel olarak, iki sayı arasında içsel bir fark olmamalıdır - bunlar sadece rakamlardır.

Buna karşılık, ondalık sayıyı 610 sayısını üretmek için diğer yönde hareket ettirirsem, hala Exactopia'dayım. Bu yönde devam edebilirim (6100, 610000000, 610000000000000) ve hala kesin, kesin, kesinler. Ancak ondalık sayı bir eşiği aşar aşmaz, sayılar artık kesin değildir.

Neler oluyor?

Düzenleme: açıklığa kavuşturmak için, IEEE gibi endüstri standardı temsiller hakkındaki tartışmalardan uzak durmak ve matematiksel olarak "saf" bir yol olduğuna inandığım şeyle uğraşmak istiyorum. Temel 10'da konumsal değerler şunlardır:

... 1000  100   10    1   1/10  1/100 ...

İkili olarak, bunlar olurdu:

... 8    4    2    1    1/2  1/4  1/8 ...

Ayrıca bu sayılar üzerinde keyfi sınırlar yoktur. Pozisyonlar süresiz olarak sola ve sağa doğru artar.


2
Kayan nokta nubmber içinde neler olup bittiğini tam olarak anlamak için bunu yararlı bulabilirsiniz: Kayan nokta sayısının anatomisi .
John D. Cook

57
İkilide, 3 sayısı 2¹ + 2 ° = 2 + 1 olarak temsil edilir. Güzel ve kolay. Şimdi 1 / 3'e bir göz atın. 2'lik negatif güçleri kullanarak bunu nasıl temsil edersiniz? Biraz deneme yapın ve 1/3 değerinin sonsuz dizinin 2 ^ -2 + 2 ^ -4 + 2 ^ -6 + 2 ^ -8 + ... toplamına eşit olduğunu göreceksiniz. ikili olarak tam olarak temsil etmek o kadar kolay değil.
Lars Haugseth

21
Jon Skeet vücudunuzdaki soruyu çok iyi yanıtlıyor. Eksik olan bir şey aslında iki farklı soru sormanızdır. Başlık sorusu "Ondalık sayılar neden tam olarak ikili olarak temsil edilemiyor?" Cevap, olabilir. Başlığınız ve bedeniniz arasında "ikili" fikrini ve "kayan nokta gösterimi" fikrini birleştiriyorsunuz. Kayan nokta, ondalık sayıları sabit sayıda ikili basamakta, kesin maliyetle ifade etmenin bir yoludur. İkili sayma için sadece farklı bir temeldir ve sonsuz sayıda basamak verildiğinde herhangi bir ondalık kutuyu ifade edebilir.
Chris Blackwell

3
Tam ondalık gösterime sahip birkaç sistem vardır. Tanımladığınız gibi çalışır. SQL ondalık türü bir örnektir. LISP dilleri yerleşik olarak bulunur. Kesin ondalık hesaplamaları kullanmak için birkaç ticari ve açık kaynak kitaplığı vardır. Sadece bunun için herhangi bir donanım desteği yoktur ve sadece birçok dil ve donanım, 32 veya 64 bitte sonsuz sayıda sayıyı temsil etmek için IEEE standartlarını uygular.
nos

1
Bu soru konu dışı gibi görünüyor çünkü matematikle ilgili (matematikle ilgili programlama olsa bile) ve Matematik
Cole Johnson

Yanıtlar:


360

Ondalık sayılar tam olarak temsil edilebilir , eğer yeterli alanınız varsa - kayan ikili nokta sayılarıyla değil. Kayan ondalık nokta türü (örn System.Decimal. .NET'te) kullanırsanız, tam olarak ikili kayan noktada gösterilemeyen çok sayıda değer tam olarak temsil edilebilir.

Başka bir şekilde bakalım - rahat edeceğiniz 10 tabanında, 1/3'ü tam olarak ifade edemezsiniz. 0.3333333 ... (yineleniyor). İkili kayan noktalı sayı olarak 0.1'i temsil edememenizin nedeni tam olarak aynı nedendir. 3 ve 9 ve 27'yi tam olarak temsil edebilirsiniz - ancak 1/3, 1/9 veya 1/27 olamaz.

Sorun, 3'ün 10 faktörü olmayan bir asal sayı olmasıdır. Bir sayıyı 3 ile çarpmak istediğinizde bu bir sorun değildir : problemlere girmeden her zaman bir tamsayı ile çarpabilirsiniz. Ama ne zaman bölmek asal ve tabanının bir faktör değildir bir sayı ile, başımı belaya çalıştırabilirsiniz (ve olacak sadece bu numara ile bölme 1 çalışırsanız bunu).

0.1 genellikle tam olarak ikili kayan nokta ile temsil edilemeyen kesin ondalık sayının en basit örneği olarak kullanılmasına rağmen, muhtemelen 0.2, 1/5 olduğu için daha basit bir örnektir ve 5, ondalık ve ikili arasında sorunlara neden olan asaldır .


Sonlu temsiller problemi ile ilgili yan not:

Kayan ondalık nokta türlerinin bazıları "keyfi olarak büyük" System.Decimalgibi sabit bir boyuta sahiptir java.math.BigDecimal- ancak sistem belleği veya bir dizinin teorik maksimum boyutu gibi bir noktada bir sınıra ulaşırlar. Ancak bu, bu cevabın ana konusuna tamamen ayrı bir noktadır. Oynamak için gerçekten keyfi olarak çok sayıda bitiniz olsa bile, tam olarak kayan bir ikili nokta gösteriminde ondalık 0.1'i temsil edemezdiniz. Bunu diğer yolla karşılaştırın: rastgele sayıda ondalık basamak verildiğinde , tam olarak kayan bir ikili nokta olarak temsil edilebilen herhangi bir sayıyı tam olarak temsil edebilirsiniz .


8
Bu çok iyi bir örnek efendim!
Tom Ritter

5
... keşke iki kere vurabilseydim. Bu konuda bana çok fazla soru soruldu. Neredeyse insanlar üs 10'un dışında düşünemiyor gibi. Hehe
Justin Niessner

38
Evet, dünyada 10 çeşit insan var - ikiliyi anlayanlar ve anlamayanlar.
duffymo

83
@JonSkeet: Ctrl + Alt + Delete yalnızca iki parmağınızla garip görünür.
Lars Haugseth

20
@muusbolla: Hayır. Ondalık gösterim 1ve ondalık gösterim 0.9...( 9ondalık noktadan sonra sonsuza kadar yinelenen s) ile temsil edilen sayılar eşittir. Belki de bunu görmenin en kolay yolu şudur: Let x = 0.9.... Unutmayın 10x = 9.9..... Dolayısıyla 9x = 10x - x = 9.9... - 0.9... = 9öyle 9x = 9ve x = 1. Bunu görmenin başka yolları da var, ama bunun en basiti olduğuna inanıyorum.
jason

25

Örneğin, 61.0 sayısı tam bir ikili temsile sahiptir, çünkü herhangi bir sayının integral kısmı her zaman doğrudur. Ancak 6.10 sayısı tam değildir. Tek yaptığım ondalık bir yeri taşımaktı ve aniden Exactopia'dan Inexactville'e gittim. Matematiksel olarak, iki sayı arasında içsel bir fark olmamalıdır - bunlar sadece rakamlardır .

Bir an için 10 ve 2 bazlarının ayrıntılarından uzaklaşalım. Temel bolarak hangi sayıların sonlandırma temsilleri var ve hangi sayılar yok? Bir anlık düşünce bir sayı söyler xbir sonlandırma sahip bbir tamsayı vardır ve ancak eğer -representation nböyle x b^nbir tam sayıdır.

Yani, örneğin, x = 11/500sonlandırıcı bir 10-temsili vardır, çünkü bir tamsayı seçebiliriz n = 3ve sonra x b^n = 22bir tam sayı seçebiliriz . Ancak x = 1/3, ne nseçersek seçelim, 3'ten kurtulamayacağız.

Bu ikinci örnek istemleri bize faktörler hakkında düşünmek ve herhangi için görebilirsiniz rasyonel x = p/q , biz asal factorisations karşılaştırarak soruya cevap verebilir (en düşük açısından olduğu varsayılır) bve q. Eğer qasal çarpanlarına ayırmada herhangi bir asal çarpan varsa , bu çarpanlardan kurtulmak biçin hiçbir zaman uygun bulamayacağız n.

Bu yüzden, zeminin 10 için bir sonlandırma temsil olmaz 2 veya 5 dışında ana faktörler yer alır.p/qq

Şimdi, 10 ve 2 numaralı tabanlara geri dönersek, sona eren 10-temsili olan herhangi bir rasyonelin p/qtam olarak asal çarpanlarına ayırma işleminde qsadece 2s ve 5s olduğunda formda olacağını görüyoruz ; ve aynı sayı q, yalnızca 2asal çarpanlarına ayırma işleminde tam olarak 2-temsile sahip olacaktır .

Ancak bu durumlardan biri diğerinin alt kümesidir! Her ne zaman

qsadece 2asal çarpanlarına ayırma

o besbelli de doğrudur yani

qasal çarpanlarına ayırma işleminde yalnızca 2s ve 5s vardır

ya da, başka bir deyişle, her p/qbir sonlandırma 2-gösterimi olan, p/qbir sonlandırma 10 gösterimi olan . Ancak bunun tersi geçerli değildir - qasal çarpanlarına ayırma işleminde 5 olduğunda , sonlandırıcı 10-temsili olacaktır, fakat sonlandırıcı 2-temsili olmayacaktır . Bu, 0.1diğer cevapların bahsettiği örnektir.

Burada sorunuzun cevabı var - çünkü 2'nin asal faktörleri 10'un asal faktörlerinin bir alt kümesi olduğundan, 2-sonlanan tüm sayılar 10-sonlanan sayılardır, ancak tam tersi değildir. 6.1'e karşı 61 değil - 10'a karşı 2.

Baz 5 kullanılan bazı cilvesi kullanılan kişiler (diyelim) tabanın 17 ama bizim bilgisayarlar tarafından, sizin sezgi bu saptırdı asla eğer bir kapanış not olarak, - orada olacağını hiç sonlandırılmış (sıfırdan farklı, tam sayı olmayan) sayılar Her iki durumda da!


Öyleyse neden "uyarı (0.15 * 0.15)" "0.0225" gösteriyor?
Michael Geiser

5
@ MichaelGeiser kısa cevap: ekran noktasında yuvarlama. Düşündüğünüz şey 0.15aslında (IEEE çift olarak saklandığında) "0.149999999999999994448884876874". Bkz. Jsfiddle .
AakashM

Nokta kodu örneğinde güzel açık! Keşke bunun için sana oy verebilseydim! Yuvarlama kesiminin nerede gerçekleştiğini keşfetmek için birkaç işlevle oynamak zorundayım. Hala bu çöple uğraşmamız gerektiğine şaşırıyorum; çünkü insanlar zamanın neredeyse% 100'ünde çalışıyorlar ve tamsayı olmayanları o kadar çok kullanıyoruz ki kayan nokta matematiğinin varsayılan uygulamasının bu saçmalıkla başa çıkacağını düşünürdünüz.
Michael Geiser

1
@MichaelGeiser, taban 2 ile çalışmak için devreler, taban 10 ile çalışmaktan daha küçük, daha hızlı ve daha güç tasarrufludur. büyük anlaşma. İşlemci devresini doğrudan desteklemeden yapmaya çalışmak daha da kötüdür, hızdaki büyüklük farklılıklarının emrini bekleyin.
Mark Ransom

Bu cevap Jon Skeet'in kendisinden daha iyi açıklıyor!
Ocak

16

Kök (matematiksel) nedeni, tamsayılarla uğraşırken, sayıca sonsuzdur .

Bu, sonsuz miktarda olsa da, dizideki tüm öğeleri, herhangi bir atlamadan "sayabiliriz" anlamına gelir. Bu, öğeyi 610000000000000listedeki th konumuna getirmek istiyorsak, bir formülle çözebiliriz.

Ancak, gerçek sayılar sayılamayacak kadar sınırsızdır . "Bana gerçek numarayı pozisyonda ver" diyemez 610000000000000ve bir cevap alamazsınız . Bunun nedeni, kayan nokta değerleri göz önüne alındığında 0ve arasında 1sonsuz sayıda değer bulunmasıdır. Aynı durum iki kayan noktalı sayı için de geçerlidir.

Daha fazla bilgi:

http://en.wikipedia.org/wiki/Countable_set

http://en.wikipedia.org/wiki/Uncountable_set

Güncelleme: Özür dilerim, soruyu yanlış yorumladım. Cevabım neden her gerçek değeri temsil edemediğimizle ilgili, kayan noktanın otomatik olarak rasyonel olarak sınıflandırıldığını fark etmemiştim.


6
Aslında, rasyonel sayılar vardır sayılabilir sonsuz. Ancak her gerçek sayı rasyonel bir sayı değildir. Kesinlikle bana vermek istediğiniz herhangi bir ondalık sayıya ulaşacak kesin ondalık sayılar dizisi üretebilirim. Eğer uğraşmak gerekir eğer var mantıksız sen uncountably sonsuz kümeler halinde olunması yanı numaralar.
Jon Skeet

Doğru, "kayan nokta" değil, "gerçek" demeliyim. Açıklığa kavuşacak.
TM.

1
Bu noktada mantık daha az uygulanabilir hale gelir, IMO - çünkü sadece ikili kayan nokta kullanan tüm gerçek sayılarla değil, tüm rasyonel sayılarla da (0.1 gibi) ilgilenemeyiz . Başka bir deyişle, bunun gerçekten sayılabilirlikle ilgisi olduğunu sanmıyorum :)
Jon Skeet

@jonskeet Jon Skeet ile aynı fikirde olmamanın temel bir doğa yasasını bozacağını biliyorum, bu yüzden tabii ki yapmayacağım :) Ancak, sayıların içsel gösterimlerini bir endeks olarak düşünmenin uygun olduğunu düşünüyorum. harici olarak temsil etmek istediğiniz değerler kümesi. Bu düşünce çizgisi ile, endekslerin listeniz (duyarlık diyelim ki, sonsuz bit vardı bile) ne kadar büyük olursa olsun, bunu görebiliyorum hala tüm gerçek sayıları temsil etmek mümkün olmaz.
TM.

3
@TM: Ama OP tüm gerçek sayıları temsil etmeye çalışmıyor. Rasyonel sayıların bir alt kümesi olan tüm kesin ondalık sayıları temsil etmeye çalışıyor ve bu nedenle sadece sayılabilir derecede sonsuz. Ondalık kayan nokta türü olarak sonsuz bir bit seti kullanıyor olsaydı iyi olurdu. Bu bitleri , ondalık sayılarla sorunlara neden olan ikili kayan nokta türü olarak kullanıyor .
Jon Skeet

10

Skeet'e yaptığım yorumda söylediğim şeyi tekrarlamak için: 1/3, 1/9, 1/27 veya ondalık gösterimde herhangi bir rasyonel temsil edebiliriz . Bunu ekstra bir sembol ekleyerek yapıyoruz. Örneğin, sayının ondalık genişlemesinde yinelenen basamakların üzerinde bir çizgi. Ondalık sayıları bir ikili sayı dizisi olarak temsil etmemiz gereken şey, 1) bir ikili sayı dizisi, 2) bir yarıçap noktası ve 3) dizinin tekrar eden kısmını göstermek için başka bir semboldür.

Hehner'ın alıntı gösterimi bunu yapmanın bir yoludur. Dizinin yinelenen kısmını temsil etmek için bir alıntı sembolü kullanır. Makale: http://www.cs.toronto.edu/~hehner/ratno.pdf ve Wikipedia girişi: http://en.wikipedia.org/wiki/Quote_notation .

Temsil sistemimize bir sembol ekleyemeyeceğimizi söyleyen hiçbir şey yoktur, bu nedenle ondalık gerekçeleri tam olarak ikili alıntı gösterimini kullanarak gösterebiliriz, ya da tam tersi.


Bu gösterim sistemi, döngünün nerede başladığını ve bittiğini bilersek çalışır. İnsanlar döngüleri saptamada oldukça iyidir. Ancak, genel olarak bilgisayarlar değildir. Bir tekrarlama sembolünü etkin bir şekilde kullanabilmek için, bilgisayarın hesaplama yaptıktan sonra döngülerin nerede olduğunu bulması gerekir. Örneğin 1/3 sayısı için döngü hemen başlar. Ancak 1/97 sayısı için, en az 96 basamağın cevabını bulana kadar döngü kendini göstermez. (Aslında, emin olmak için 96 * 2 + 1 = 193 basamak gerekir.)
Barry Brown

4
Aslında bilgisayarın çevrimi algılaması hiç de zor değil. Hehner'ın makalesini okursanız, çeşitli aritmetik işlemler için döngüleri nasıl tespit edeceğini açıklar. Örneğin, tekrarlanan çıkarma kullanan bölme algoritmasında, daha önce gördüğünüz bir farkı gördüğünüzde döngünün nerede başladığını bilirsiniz.
ntownsend

3
Ayrıca, soru sayıları tam olarak temsil etmekti. Bazen tam temsil çok sayıda bit anlamına gelir. Alıntı gösteriminin güzelliği, Hehner'ın standart 32 bit sabit uzunluklu gösterime kıyasla ortalama olarak temsil boyutunda% 31'lik bir tasarruf olduğunu göstermesidir.
ntownsend

6

BCD - İkili kodlu Ondalık - gösterimler doğrudur. Çok yer tasarruflu değiller, ancak bu durumda doğruluk için yapmanız gereken bir değiş tokuş.


1
BCD diğer bazlardan daha fazla veya daha az kesin değildir. Örnek: 1/3'ü tam olarak BCD'de nasıl temsil ediyorsunuz? Yapamazsın.
Jörg W Mittag

12
BCD, bir DECIMAL'in tam temsilidir, dolayısıyla adının "ondalık" kısmıdır. 1/3'ün kesin ondalık gösterimi de yoktur.
Alan

4

Aynı temelde 10'u 1/3'ü temsil edememenizin nedeni de 0.33333 (3) demeniz gerekir. İkili olarak aynı tür bir sorundur, ancak sadece farklı sayılar kümesi için oluşur.


4

(Not: Burada ikili sayıları belirtmek için 'b' ekleyeceğim. Diğer tüm sayılar ondalık olarak verilir)

Bir şeyleri düşünmenin bir yolu bilimsel gösterim gibi bir şeydir. 6.022141 * 10 ^ 23 gibi bilimsel gösterimde ifade edilen sayıları görmeye alışkınız. Kayan nokta numaraları dahili olarak benzer bir format kullanılarak saklanır - mantis ve üs, ancak on yerine iki güç kullanılarak.

61.0 değeriniz mantis ve üslerle 1.90625 * 2 ^ 5 veya 1.11101b * 2 ^ 101b olarak yeniden yazılabilir. Bunu on ile çarpmak ve (ondalık noktasını taşımak) için şunları yapabiliriz:

(1.90625 * 2 ^ 5) * (1.25 * 2 ^ 3) = (2.3828125 * 2 ^ 8) = (1.19140625 * 2 ^ 9)

veya ikili mantis ve üslerle birlikte:

(1.11101b * 2 ^ 101b) * (1.01b * 2 ^ 11b) = (10.0110001b * 2 ^ 1000b) = (1.00110001b * 2 ^ 1001b)

Sayıları çarpmak için orada ne yaptığımıza dikkat edin. Mantisayı çoğalttık ve üsleri ekledik. Sonra, mantis ikiden fazla bittiğinden, üssü çarparak sonucu normalleştirdik. Aynen ondalık bilimsel gösterimde sayılar üzerinde bir işlem yaptıktan sonra üssü ayarladığımızda olduğu gibi. Her iki durumda da birlikte çalıştığımız değerler ikili olarak sonlu bir temsile sahipti ve bu nedenle temel çarpma ve toplama işlemleriyle elde edilen değerler de sonlu bir temsile sahip değerler üretti.

Şimdi, 61'i 10'a nasıl böldüğümüzü düşünün. 1.90625 ve 1.25 mantislerini bölerek başlayacağız. Ondalık olarak, bu 1.525, güzel bir kısa sayı verir. Ama bunu ikiliye dönüştürürsek bu nedir? Bunu her zamanki gibi yapacağız - tamsayı ondalık sayıları ikiliye dönüştürmek gibi, mümkün olduğunca ikinin en büyük gücünü çıkarmak, ancak ikisinin negatif güçlerini kullanacağız:

1.525-1 * 2 ^ 0 -> 1
0.525-1 * 2 ^ -1 -> 1
0,025 - 0 * 2 ^ -2 -> 0
0,025 - 0 * 2 ^ -3 -> 0
0,025 - 0 * 2 ^ -4 -> 0
0,025 - 0 * 2 ^ -5 -> 0
0,025-1 * 2 ^ -6 -> 1
0.009375 - 1 * 2 ^ -7 -> 1
0.0015625 - 0 * 2 ^ -8 -> 0
0.0015625 - 0 * 2 ^ -9 -> 0
0.0015625 - 1 * 2 ^ -10 -> 1
0.0005859375 - 1 * 2 ^ -11 -> 1
,00009765625 ...

Ah oh. Şimdi başımız belada. 1.90625 / 1.25 = 1.525, ikili olarak ifade edildiğinde tekrar eden bir kesir olduğu ortaya çıktı: 1.11101b / 1.01b = 1.10000110011 ... b Makinelerimiz bu mantis için sadece çok fazla bite sahipler ve böylece kesri yuvarlayacaklar ve belli bir noktanın ötesinde sıfır olduğunu varsayalım. 61'i 10'a böldüğünüzde gördüğünüz hata aşağıdakiler arasındaki farktır:

1.100001100110011001100110011001100110011 ... b * 2 ^ 10b
ve deyin:
1.100001100110011001100110b * 2 ^ 10b

Kayan nokta değerleri ile ilişkilendirdiğimiz hassasiyet kaybına yol açan mantis bu yuvarlamadır. Mantis tam olarak ifade edilebildiğinde bile (örneğin, sadece iki sayı eklerken), eğer mantis üs normalleştirildikten sonra sığmayacak kadar çok basamağa ihtiyaç duyarsa, yine de sayısal kayıplar elde edebiliriz.

Ondalık sayıları yönetilebilir bir boyuta yuvarladığımızda ve sadece ilk birkaç basamağını verdiğimizde bu tür şeyleri her zaman yapıyoruz. Sonucu ondalık olarak ifade ettiğimiz için doğal geliyor. Ancak, bir ondalık sayıyı yuvarlayıp daha sonra farklı bir tabana dönüştürürsek, kayan nokta yuvarlaması nedeniyle elde ettiğimiz ondalık sayılar kadar çirkin görünecektir.


4

Bu iyi bir soru.

Tüm sorunuz "sayıyı nasıl temsil ediyoruz?"

TÜM sayılar ondalık gösterimle veya ikili (2'nin tamamlayıcısı) gösterimi ile temsil edilebilir. Hepsi !!

FAKAT bazı (çoğu) sonsuz sayıda eleman gerektirir (ikili konum için "0" veya "1" veya ondalık gösterim için "0", "1" ila "9").

Ondalık gösterimde 1/3 gibi (1/3 = 0.3333333 ... <- sonsuz sayıda "3" ile)

İkili 0.1 gibi (0.1 = 0.00011001100110011 .... <- sonsuz sayıda "0011" ile)

Her şey bu kavramda. Bilgisayarınız yalnızca sonlu düşünebildiğinden basamak kümesini (ondalık veya ikili) , yalnızca bazı sayılar bilgisayarınızda tam olarak temsil edilebilir ...

Ve Jon'un dediği gibi, 3, 10 faktörü olmayan bir asal sayıdır, bu nedenle 1/3 sonlu ile temsil edilemez taban 10'daki sayıda elemanla .

Keyfi hassasiyetle aritmetik olsa bile, taban 2'deki numaralandırma konumu sistemi 61'i temsil edebilmesine rağmen 6.1'i tam olarak tanımlayamaz.

6.1 için başka bir gösterim kullanmalıyız (ondalık gösterim veya kayan nokta değerlerinin temsili için taban 2 veya taban 10'a izin veren IEEE 854 gibi)


Kesirin kendisi olarak 1/3'ü temsil edebilirsiniz. Onu temsil etmek için sonsuz miktarda bite ihtiyacınız yoktur. Sadece 1 alıp 3'e bölmek yerine 1/3 kesiri olarak temsil edersiniz. Birkaç sistem bu şekilde çalışır. Daha sonra kesirlerin temsili üzerinde çalışmak için standart / * + - ve benzer operatörleri kullanmanın bir yoluna ihtiyacınız var, ancak bu oldukça kolay - bu işlemleri bir kalem ve kağıtla yapabilirsiniz, bir bilgisayara öğretmesi çok önemli değil .
nos

"İkili (2'nin tamamlayıcısı) temsili" hakkında konuşuyordum. Elbette, bir başka temsilini kullanarak temsil etmeye yardımcı olabilir, çünkü bazı elementlerin sonlu sayı ile sayı (ve bazı diğerleri için elementlerin sonsuz sayıda gerekir)
ThibThib

3

Kayan nokta ile yeterince büyük bir sayı yaparsanız (üsler yapabileceği gibi), ondalık noktanın önünde de hatalı olursunuz. Bu yüzden sorunuzun tamamen geçerli olduğunu düşünmüyorum çünkü öncül yanlış; 10'a kadar kaydırmanın her zaman daha fazla hassasiyet yaratacağı durum böyle değildir, çünkü bir noktada kayan nokta sayısı sayının büyüklüğünü temsil etmek için üsleri kullanmak zorunda kalacak ve bu şekilde de bazı hassasiyetlerini kaybedecektir.


3

Henüz kimsenin bunu söylemediğine şaşırdım: sürekli kesirler kullanın . Herhangi bir rasyonel sayı bu şekilde ikili olarak sonlu olarak temsil edilebilir.

Bazı örnekler:

1/3 (0.3333 ...)

0; 3

5/9 (0.5555 ...)

0; 1, 1, 4

10/43 (0.232558139534883720930 ...)

0; 4, 3, 3

9093/18478 (0.49209871198181621387596060179673 ...)

0; 2, 31, 7, 8, 5

Buradan, bir tamsayı dizisini hafızaya kaydetmenin bilinen çeşitli yolları vardır.

Numaranızı mükemmel bir doğrulukla saklamanın yanı sıra, sürekli kesirlerin en iyi rasyonel yaklaşım gibi başka faydaları da vardır. Devam eden bir kesir içindeki sayı dizisini erken sonlandırmaya karar verirseniz, kalan basamaklar (bir kesire yeniden birleştirildiğinde) size mümkün olan en iyi kesri verecektir. Pi'ye yaklaşımlar şu şekilde bulunur:

Pi'nin devam eden kesiri:

3; 7, 15, 1, 292 ...

Sekansı 1'de sonlandırmak, bu kesri verir:

355/113

ki bu mükemmel bir rasyonel yaklaşımdır.


Fakat bunu ikili dosyada nasıl temsil edersiniz? Örneğin 15, 4 bitin temsil edilmesini gerektirir, ancak 292, 9 gerektirir. Donanım (hatta yazılım), bit sınırlarının her biri arasında nerede olduğunu nasıl bilir? Bu, doğruluk dengesine karşı verimliliktir.
ateşli

2

Denklemde

2^x = y ;  
x = log(y) / log(2)

Bu yüzden, ikili gibi logaritmik bir temel sistemimiz olup olmadığını merak ediyordum,

 2^1, 2^0, 2^(log(1/2) / log(2)), 2^(log(1/4) / log(2)), 2^(log(1/8) / log(2)),2^(log(1/16) / log(2)) ........

Bu sorunu çözebilir, bu yüzden ikili dosyaya 32.41 gibi bir şey yazmak istersen,

2^5 + 2^(log(0.4) / log(2)) + 2^(log(0.01) / log(2))

Veya

2^5 + 2^(log(0.41) / log(2))

1

Sorun, sayının gerçekten 61.0 olup olmadığını gerçekten bilmemenizdir. Bunu düşün:


float a = 60;
float b = 0.1;
float c = a + b * 10;

C'nin değeri nedir? Tam olarak 61 değildir, çünkü b gerçekten .1 değildir, çünkü .1 tam bir ikili temsile sahip değildir.


1

Bir eşik var çünkü rakamın anlamı tamsayıdan tamsayıya geçmiştir. 61'i temsil etmek için 6 * 10 ^ 1 + 1 * 10 ^ 0; 10 ^ 1 ve 10 ^ 0 her ikisi de tamsayıdır. 6.1 6 * 10 ^ 0 + 1 * 10 ^ -1'dir, ancak 10 ^ -1 1/10'dur, bu kesinlikle bir tamsayı değildir. Sonuç olarak Inexactville ile karşılaşıyorsunuz.


1

Paralel kesirler ve tam sayılardan yapılabilir. Bazı kesirler, örneğin 1/7, çok ve ondalık sayılar olmadan ondalık formda gösterilemez. Kayan nokta ikili tabanlı olduğu için özel durumlar değişir, ancak aynı tür doğruluk problemleri ortaya çıkar.


0

Sonsuz sayıda rasyonel sayı ve bunları temsil etmek için sınırlı sayıda bit vardır. Bkz. Http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems .


Ancak sonsuz sayıda bitle bile, kayan bir ikili nokta kullansaydınız , yine de tam olarak 0.1'i temsil edemezdiniz, tıpkı sonsuz sayıda bitle bile ondalık olarak tam olarak 1/3'ü temsil edemeyeceğiniz gibi.
Jon Skeet

3
@Jon Bu yanlış: sonsuz sayıda ondalık ile, örneğin 'üçte birini' tam olarak ifade edebilirim . Gerçek dünya problemi "sonsuz sayıda" ondalık sayıya veya bitlere sahip olmak fiziksel olarak mümkün değildir .
ChrisW

0

61.0 sayısının gerçekte tam bir kayan nokta işlemi var - ancak bu herkes için doğru değil tamsayılar . Hem çift kesinlikli kayar nokta numarasına hem de 64 bitlik bir tam sayıya bir tane eklediyseniz, sonunda 64 bitlik tamsayının bir sayıyı mükemmel olarak temsil ettiği bir noktaya ulaşırsınız, ancak kayan nokta - çünkü yeterince önemli bit yok.

Ondalık noktanın sağ tarafında yaklaşık noktaya ulaşmak çok daha kolaydır. Tüm sayıları ikili kayan nokta ile yazmaya başlarsanız, daha anlamlı olur.

Bunu düşünmenin başka bir yolu da, 61.0'ın taban 10'da mükemmel bir şekilde temsil edilebilir olduğunu ve ondalık noktayı kaydırmanın bunu değiştirmediğini fark ettiğinizde, on (10 ^ 1, 10 ^ -1 güç ile çarpma gerçekleştirdiğinizdir. ). Kayan noktada, ikisinin gücü ile çarpmak sayının kesinliğini etkilemez. Mükemmel kesin bir sayının kesin temsilini nasıl kaybedebileceğinin bir örneği için 61.0'ı almayı ve art arda üçe bölmeyi deneyin.


0

tam sayıları biliyorsunuz değil mi? her bit 2 ^ n'yi temsil eder


2 ^ 4 = 16
2 ^ 3 = 8
2 ^ 2 = 4
2 ^ 1 = 2
2 ^ 0 = 1

kayan nokta için de aynıdır (bazı ayrımlarla), ancak bitler 2 ^ -n 2 ^ -1 = 1/2 = 0.5
2 ^ -2 = 1 / (2 * 2) = 0.25
2 ^ -3 = 0.125
2 ^ -4 = 0.0625

Kayan nokta ikili gösterimi:

işareti Üst Kesir (fraksiyona görünmez 1'in eklendiğini düşünüyorum)
B11 B10 B9 B8 B7 B6 B5 B4 B3 B2 B1 B0


0

Yukarıdaki yüksek puanlama cevabı çivilenmiştir.

İlk önce sorunuzda baz 2 ve baz 10'u karıştırıyordunuz, daha sonra sağ tarafa tabana bölünemeyen bir sayı koyduğunuzda sorun yaşıyorsunuz. Ondalık sayının 1 / 3'ü gibi, çünkü 3, 2 gücüne girmeyen 10 veya 1/5'lik bir iktidara gitmez.

Yine başka bir yorum ASLA kayan nokta sayıları, nokta eşit kullanmayın. Kesin bir temsil olsa bile, bazı kayan nokta sistemlerinde birden fazla şekilde doğru bir şekilde temsil edilebilen bazı sayılar vardır (IEEE bu konuda kötüdür, başlamak için korkunç bir kayan nokta özelliğidir, bu yüzden baş ağrılarını bekleyin). Burada hiçbir fark 1/3, ondalık noktanın sağında kaç tane 3 olursa olsun, hesap makinenizdeki sayıya eşit değildir 0.3333333. Yeterince yakın veya olabilir ama eşit değildir. böylece 2 * 1/3 gibi bir şeyin yuvarlamaya bağlı olarak 2/3'e eşit olmasını beklemezsiniz. Asla kayan nokta ile eşit kullanmayın.


0

Tartıştığımız gibi, kayan nokta aritmetiğinde, ondalık 0.1, ikili olarak mükemmel bir şekilde temsil edilemez.

Kayan nokta ve tamsayı gösterimleri, temsil edilen sayılar için ızgaralar veya kafesler sağlar. Aritmetik yapıldıkça, sonuçlar ızgaradan düşer ve yuvarlayarak ızgaraya geri konulmalıdır. İkili bir ızgarada örnek 1/10'dur.

Bir beyefendinin önerdiği gibi ikili kodlu ondalık gösterimi kullanırsak, sayıları ızgarada tutabilir miyiz?


1
Ondalık sayılar, elbette. Ama bu sadece tanım gereği. Ondalık olarak 1 / 3'ü, ikili olarak 0,1'i temsil edebileceğinizden daha fazla temsil edemezsiniz. Herhangi bir nicemleme şeması, sonsuz büyüklükte bir sayı kümesi için başarısız olur.
Kylotan
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.