Float vs ondalık ne zaman kullanılır?


14

Bu API oluşturuyorum ve veritabanı aşağıdakilerden birini temsil eden değerleri depolar:

  • yüzde
  • ortalama
  • oran

Dürüst olmak gerekirse, aralıktaki sayıların% 0 ila 100 arasında olduğu bir şeyi nasıl temsil edeceğime dair hiçbir fikrim yok. Olmalı mı

  • 0.00 - 1.00
  • 0.00 - 100.00
  • bilmediğim başka bir alternatif

Bunun için açık bir seçim var mı? Veritabanlarında% 0 ile% 100 arasında değişen bir şeyi temsil etmenin küresel bir yolu mu? Daha ileri gitmek, bunun için doğru olan tür nedir, kayan veya ondalık?

Teşekkür ederim.



5
Sayılar birçok şekilde saklanabilir. 0-100 kullanarak veya 0-1 kullanarak yüzde depolamakta doğal olarak yanlış bir şey yoktur. Önemli olan, sayılarla ne yapmanız gerektiği, ihtiyacınız olan doğruluk, vb. İyi bir cevap verilmeden önce daha fazla bağlam açıklamalısınız. Az sayıda ondalık basamakla tam olarak temsil edilebilen sayıları saklamanız mı gerekiyor? Bir şeyleri ortalamalandırırsanız, üçte veya yedinci gibi kesirler elde edersiniz. Bunları tam olarak depolamanız mı gerekiyor? Yoksa sadece mi? Ne kadar? Onlarla ne yapacaksın?
Eric Postpischil

1
Değerler 0,01'lik adımlarla 0,00 ila 100,00 ise, bu 10001 farklı değerdir. Sadece yüzlerce , Permyriad veya ‱ birimlerini inttemsil etmek için a kullanın .
chux - Monica

@ chux-ReinstateMonica - Evet, "ölçeklendirilmiş tamsayılar" mümkündür, ancak sakar.
Rick James

@RickJames Belki. Ölçekli tam sayıları zor bulamadım.
chux - Monica

Yanıtlar:


4

Ben tam tersine bakacağım.

FLOATyüzdeler, ortalamalar, vb. gibi yaklaşık sayılar içindir. Değerleri uygulama kodunda veya FORMAT()MySQL işlevini kullanarak görüntülerken biçimlendirme yapmanız gerekir .

Hiç test etme float_value = 1.3; bunun başarısız olmasının birçok nedeni var.

DECIMALparasal değerler için kullanılmalıdır. DECIMALBir değerin dolar / sent / euro / vb. değerine yuvarlanması gerektiğinde ikinci bir yuvarlamayı önler. Muhasebeciler sent fraksiyonlarını sevmezler.

MySQL'in uygulanması DECIMAL65 önemli basamak sağlar; FLOAT7 ve DOUBLEyaklaşık 16 verir . 7 genellikle sensörler ve bilimsel hesaplamalar için fazlasıyla yeterlidir.

"Yüzde" gelince - Bazen TINYINT UNSIGNEDsadece 1 bayt depolama tüketmek ve çok fazla hassasiyete gerek duymadığımda kullandım; bazen kullandım FLOAT(4 bayt). Yüzde için özel olarak ayarlanmış bir veri türü yoktur. (Ayrıca, DECIMAL(2,0)değeri tutamayacağını unutmayın, bu 100nedenle teknik olarak ihtiyacınız olacaktır DECIMAL(3,0).)

Veya bazen FLOAT0 ile 1 arasında bir değer tutan bir kullandım . Ama sonra "yüzde" görüntülemeden önce 100 ile çarpmak emin olmak gerekir.

Daha

"Yüzde, ortalama, oran" üçü de yüzer gibi kokuyor, bu yüzden benim ilk tercihim olurdu.

Veri tipine karar vermek için bir kriter ... Değerin kaç kopyası var?

Yüzde sütun içeren milyar satırlık bir tablonuz varsa, bunun TINYINT1 bayt (toplam 1 GB), ancak FLOAT4 bayt (toplam 4 GB) alacağını düşünün . OTOH, çoğu uygulamada bu kadar satır yoktur, bu nedenle bu uygun olmayabilir.

"Genel" bir kural olarak, "tam" değerler bir INTveya biçimini kullanmalıdır DECIMAL. Hatalı şeyler (bilimsel hesaplamalar, karekökler, bölünme, vb.) Kullanmalı FLOAT(veya DOUBLE).

Ayrıca, çıktının biçimlendirmesi genellikle uygulamanın ön ucuna bırakılmalıdır. Yani, bir "ortalama" "14.6666666 ..." olarak hesaplanabilse de, ekran "14.7" gibi bir şey göstermelidir; bu insanlar için dostça. Bu arada, daha sonra "15" veya "14.667" tercih edilen çıktı biçimlendirme olduğuna karar vermek için temel değere sahipsiniz.

"0.00 - 100.00" aralığı , her zaman belirtilen hassasiyeti isteyeceğiniz ön belirleme ile FLOAT çıktı biçimlendirmesi ile veya DECIMAL(5,2)(3 bayt) ile yapılabilir .


3

Genellikle kullanmaya karşı tavsiye ederim float. Kayan nokta sayıları, taban-2'deki sayıları temsil eder, bu da bazı (kesin) sayıların işlemlerde veya karşılaştırmalarda yuvarlanmasına neden olur, çünkü taban-2'de doğru bir şekilde saklanamazlar. Bu şaşırtıcı davranışlara yol açabilir.

Aşağıdaki örneği düşünün :

create table t (num float);
insert into t values(1.3);

select * from t;

| num |
| --: |
| 1.3 |

select * from t where num = 1.3;

| num |
| --: |

Temel-2 sayı karşılaştırması 1.3başarısız olur. Bu zor.

Buna karşılık, ondalık, sonlu sayıların kendi aralıkları dahilinde doğru bir temsilini sağlar. Eğer değiştirirseniz floatiçin decimal(2, 1)yukarıdaki örnekte, beklenen sonuçları elde yapmak.


4
Bu cevap birçok açıdan yanlıştır. “Buna karşılık, ondalık aralığın daha küçük bir aralığı vardır ancak bu aralıktaki sonlu sayıların tam bir temsilini sağlar” yanlıştır: Ondalık ⅓ tam olarak temsil etmez. “Bazı (kesin, sonlu) sayılar yuvarlanıyor” yanlış; sayılar "yuvarlama" değildir. Dönüşümler ve diğer işlemler yuvarlanabilir. Varsayılan yuvarlama modu, en çok yuvarlama değil, en sık bağlamaya eşittir.
Eric Postpischil

4
Doğrulukla ilgili konular “Kayan nokta sayıları” değil, sadece sayısal gösterimlerden kaynaklanmaktadır: Tüm sonlu sayısal gösterimlerin doğruluğu sınırlıdır: Kayan nokta, sabit nokta, tamsayı, rasyonel, ondalık, ikili, her şey.
Eric Postpischil

2
İç çekmek. Ne düzelttin? Benim yorumum cevabın yanlış olduğunu söylüyor, çünkü ondalık sayının kendi aralığındaki sayıların tam bir temsilini sağladığını söylüyor, ama aslında öyle değil çünkü ⅓'nın tam bir temsilini sunmuyor. Değişiklik “kesin” yerine “doğru” diyor, ancak o zaman neden ikili kayan nokta o kadar iyi değil - ikisi de kesin değil ve ikisi de veya ikisi de doğru, eşik değerinizin ne olduğuna ve ne kadar hassasiyete bağlı olarak doğru onlar sahip. Soru, ortalamaların temsil edileceğini ve üç şeyin ortalamasının size ⅓ gibi sayılar verdiğini gösterir.
Eric Postpischil

4
Yorumda, en yakınına-hatta-bağların en sık kullanıldığı söyleniyor, ancak cevap hala toparlanma diyor. Cevap karşılaştırmalar yuvarlanabilir, ancak karşılaştırma mükemmeldir: Karşılaştırmalar her zaman yuvarlama olmadan matematiksel olarak doğru bir sonuç döndürür. (Bazı programlama dilleri karşılaştırma yapmadan önce işlenenleri dönüştürebilir, ancak bunlar ayrı işlemlerdir.)
Eric Postpischil

1
1/3 tam olarak ikili veya ondalık olarak gösterilemez. 14,99 $ 'lık% 20 indirim, kesirli sentlerin yuvarlanmasını gerektirmez.
Rick James

0

Şamandıra ve ondalık arasındaki fark hassasiyettir. Ondalık,% 100 ondalık biçimin kesinliği dahilindeki herhangi bir sayıyı doğru olarak temsil ederken, Float tüm sayıları doğru bir şekilde temsil edemez.

Finansal ile ilgili değer için Ondalık kullanın ve örneğin grafikle ilgili değer için kayan nokta kullanın


0

Kesin hassasiyeti korumak için decimal(5,2)kullanacağınız şekilde saklayacaksanız kullanmanızı tavsiye ederim decimal. (Bkz. Https://dev.mysql.com/doc/refman/8.0/en/fixed-point-types.html )

Kayan nokta değerleri yaklaşık olduğundan ve kesin değerler olarak saklanmadığından, karşılaştırmalarda kesin olarak ele alma girişimleri sorunlara yol açabilir. Ayrıca platform veya uygulama bağımlılıklarına da tabidirler.

( https://dev.mysql.com/doc/refman/8.0/en/floating-point-types.html )

SQL ifadesinde yazılan kayan nokta değeri, dahili olarak temsil edilen değerle aynı olmayabilir.

DECIMAL sütunları için MySQL, en yaygın yanlışlık sorunlarını çözmesi gereken 65 ondalık basamak hassasiyetiyle işlemler gerçekleştirir.

https://dev.mysql.com/doc/refman/8.0/en/problems-with-float.html


0

Ondalık: Finansal uygulamalarda, Ondalık türleri kullanmak daha iyidir, çünkü size yüksek düzeyde doğruluk sağlar ve yuvarlama hatalarından kaçınmak kolaydır

Çift: Çift Türler, para işlemek dışında gerçek değerler için muhtemelen en çok kullanılan veri türüdür.

Şamandıra: Çoğunlukla grafik kütüphanelerinde kullanılır, çünkü işlem gücü için çok yüksek talepler, aynı zamanda yuvarlama hatalarına dayanabilecek durumlar da kullanılır.

Referans: http://net-informations.com/q/faq/float.html


0
mysql> create table numbers (a decimal(10,2), b float);
mysql> insert into numbers values (100, 100);
mysql> select @a := (a/3), @b := (b/3), @a * 3, @b * 3 from numbers \G

*********************************************************************

@a := (a/3): 33.333333333
@b := (b/3): 33.333333333333
@a + @a + @a: 99.999999999000000000000000000000
@b + @b + @b: 100

Ondalık bu vakalarda tam olarak ne yapması gerektiğini yaptı, gerisini kısalttı, böylece 1/3 bölümünü kaybetti.

Yani toplamlar için ondalık daha iyidir, ancak bölünmeler için şamandıra elbette bir noktaya kadar daha iyidir. Demek istediğim, DECIMAL kullanmak hiçbir şekilde "başarısızlığa dayanıklı aritmetik" vermeyecektir.

Umarım bu yardımcı olacak.


0

Tsql'de: Float, 0.0 0 olarak saklanır ve ondalık basamaktan sonra tanımlanması gerekmez, örneğin Float (4,2) yazmanız gerekmez. Ondalık, 0,0, 0,0 olarak saklanır ve ondalık (4,2) gibi tanımlama seçeneği vardır, 0,00-1,00 öneririm, bunu yaparak yüzde ile 100'ü çarpmadan değerini hesaplayabilirsiniz ve rapor ederseniz veri türünü ayarlayın Bu sütunun MS Excel ve diğer platform görünümleri gibi yüzde olarak 0.5 -> 50%.

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.