Örneğin, dolar ile, 0,01 $ 'dan daha düşük bir hassasiyetiniz olmaz
Gerçekten?
para birimini neden IEEE 754 kayan nokta numarası olarak depolamamanız gerektiğiyle ilgili eski sorun.
Lütfen inçleri IEEE 754 kayan nokta numaralarında saklamaktan çekinmeyin . Tam olarak nasıl beklediğinizi depolarlar.
Lütfen cetveli bir inçlik kesimlere bölen keneleri kullanarak saklayabileceğiniz herhangi bir miktarda parayı IEEE 754 kayan nokta numaralarına depolamaktan çekinmeyin .
Neden? Çünkü IEEE 754'ü kullandığınızda bu şekilde saklıyorsunuz.
İnç ile ilgili olan şey yarıya bölünmüş olmalarıdır. Çoğu para birimi türüyle ilgili olan şey, onda birine bölünmüş olmasıdır (bazı türler odaklanmaz ancak odaklanalım).
Bu fark, çoğu programlama dili için, IEEE 754 kayan nokta numaralarına giriş ve çıkışların ondalık sayılarla ifade edilmesi dışında kafa karıştırıcı değildir ! Bu çok garip çünkü ondalık sayılarda saklanmıyorlar.
Bu nedenle , bilgisayardan saklamasını istediğinizde , bitlerin nasıl garip şeyler yaptığını asla göremezsiniz0.1
. Sadece ona karşı matematik yaptığınızda garipliği görüyorsunuz ve garip hataları var.
Gönderen Josh Bloch'un etkili java :
System.out.println(1.03 - .42);
üretir 0.6100000000000001
Bu konuda en çok söylediklerimiz 1
sağ tarafta oturan yol değil. Bunu elde etmek için kullanılması gereken tuhaf rakamlar. En popüler örneği kullanmak yerine 0.1
, sorunu gösteren ve gizleyecek yuvarlamayı önleyen bir örnek kullanmalıyız.
Örneğin, bu neden işe yarıyor?
System.out.println(.01 - .02);
üretir -0.01
Çünkü şanslıyız.
Bazen "şanslı" olduğum için teşhis edilmesi zor problemlerden nefret ediyorum.
IEEE 754 0.1'i tam olarak depolayamaz. Ama eğer 0.1 saklamasını ve sonra yazdırmasını istersen 0.1 gösterecek ve her şeyin yolunda olduğunu düşüneceksin. İyi değil, ama göremiyorsunuz çünkü 0.1'e geri dönmek için yuvarlanıyor.
Bazı insanlar bu farklılıkları yuvarlama hatalarını çağırarak diğerlerinin kafasını karıştırır. Hayır, bunlar yuvarlama hataları değil. Yuvarlama, olması gerekeni yapıyor ve ondalık olmayanı ondalık sayıya dönüştürüyor, böylece ekranda yazdırabiliyor.
Ancak bu, sayının nasıl görüntüleneceği ve nasıl saklandığı arasındaki uyuşmazlığı gizler. Yuvarlama gerçekleştiğinde hata olmadı. Tam olarak depolayamayan bir sisteme bir sayı koymaya karar verdiğinizde ve tam olarak depolanmadığı zaman varsayıldığı zaman oldu.
Kimse π kesin bir hesap makinesinde saklamak için beklemiyor ve onunla iyi çalışmayı başarıyor. Yani sorun hassasiyetle ilgili değil. Beklenen hassasiyetle ilgilidir. Bilgisayarlar 0.1
hesap makinemizin onda birini gösterir , bu nedenle hesap makinelerinin onda biri kadar mükemmel bir şekilde saklanmalarını bekleriz. Yapmazlar. Bu şaşırtıcı, çünkü bilgisayarlar daha pahalı.
Size uyuşmazlığı göstereyim:
1/2 ve 0.5'in mükemmel bir şekilde sıralandığına dikkat edin. Ancak 0.1 sıraya girmiyor. Tabii eğer 2'ye bölmeye devam ederseniz daha da yaklaşabilirsiniz ama asla tam olarak vurmayacaksınız. Ve her 2'ye bölüştüğümüzde daha fazla bite ihtiyacımız var. Yani, 2'ye bölen herhangi bir sistemle 0.1'i temsil etmek sonsuz sayıda bite ihtiyaç duyar. Sabit diskim o kadar büyük değil.
Böylece IEEE 754 , bitleri bittiğinde denemeyi durdurur. Hangi güzel çünkü aile fotoğrafları için sabit diskimde yer gerekir. Gerçekten değil. Aile fotoğrafları. : P
Her neyse, yazdıklarınız ve gördükleriniz ondalık sayılardır (sağda), ancak sakladığınız şey çifttir (solda). Bazen bunlar tamamen aynıdır. Bazen değiller. Bazen öyle olmadıklarında aynı gibi görünüyorlar. Yuvarlama bu.
Özellikle, değerleri bir para biriminde saklayabilmek ve yazdırabilmek için nelere ihtiyacımız var?
Lütfen, ondalık tabanlı paramı işliyorsanız şamandıra veya iki kat kullanmayın.
Onuncu kuruş gibi şeylerin dahil olmayacağından eminseniz, sadece kuruşları saklayın. O zaman bu para biriminin en küçük biriminin ne olacağını anlamaya çalışın ve bunu kullanın. Yapamıyorsanız , BigDecimal gibi bir şey kullanın .
Benim net değer muhtemelen her zaman iyi bir 64 bit tamsayı sığacak ama BigInteger gibi şeyler bundan daha büyük projeler için iyi çalışır. Yerli tiplerden daha yavaşlar.
Nasıl saklanacağını bulmak sorunun sadece yarısıdır. Bunu da görüntüleyebilmeniz gerektiğini unutmayın. İyi bir tasarım bu iki şeyi ayıracaktır. Burada şamandıra kullanmanın asıl sorunu, bu iki şeyin birbirine karışmasıdır.