Sabit olarak sıfır mı?


15

Son zamanlarda bu programlama deyimiyle karşılaştım:

const float Zero = 0.0;

daha sonra karşılaştırmalarda kullanılır:

if (x > Zero) {..}

Herkes bunun gerçekten daha verimli veya okunabilir veya bakımı kolay olup olmadığını açıklayabilir:

if (x > 0.0) {..}

NOT: Bu sabiti tanımlamak için başka nedenler düşünebilirim, sadece bu bağlamda kullanımını merak ediyorum .


31
Geliştiriciler kodu matematik yasalarının farklı olduğu bir evrene taşımayı planlıyorlar mı?
vaughandroid

6
Ciddi olsa da, bunun için iyi bir neden düşünemiyorum. Gelebileceğim tek açıklamalar, aşırı gayretli kodlama standartları veya "sihirli sayılar kötü" duymuş ancak nedenini (ya da sihirli bir sayıyı neyin oluşturacağını) anlamamış bazı geliştiriciler ...
vaughandroid

@ Baqueta -Alternatif bir evren mi? Sanırım zaten orada yaşıyorlar! Sihirli sayılara gelince, katılıyorum, ancak 0 ve 1 hariç her şeyin sabit hale getirilmesi gerektiğinin temel kuralını kullanıyorum .
NWS

1
Eğer xtürü vardır float, o x > 0.0terfi zorlar doubleaz verimli olması olabilir. Bu senin sabitleri (örneğin doğru tip Sadece emin olmak için, adlandırılmış sabit olsa kullanmak için iyi bir neden değil 0f, float(0)ya da decltype(x)(0)).
Mike Seymour

1
@JoSo: Adil olmak gerekirse , öyle 13.37değil . Yani eğer bir istedik o zaman akla senin öğretmen doğruydu. Bazı bağlamlarda (örn. Bir kayan noktaya atama) örtük olarak istediğiniz şeye dönüştürülecektir ve diğer bağlamlarda (örneğin şablon türü kesinti) olmayacaktır, her zaman amaçladığınız tür olarak başlar. Bu nedenle, daha güvenli. Dikkat et, öyle olur ! Ancak makrodan kaçınmanın "tip güvenlik" ten başka nedenleri de vardır, bu nedenle öğretmen size kötü bir argüman veriyor olabilir. floatdoublefloat13.37floatstatic const float13.37f
Steve Jessop

Yanıtlar:


29

Olası nedenler önbellekleme, adlandırma veya zorlama türüdür

Önbellekleme (uygulanamaz)

Karşılaştırma işlemi sırasında bir nesne oluşturma maliyetinden kaçınmak istersiniz. Java'da bir örnek

BigDecimal zero = new BigDecimal ("0.0");

bu oldukça ağır bir oluşturma sürecini içerir ve sağlanan statik yöntem kullanılarak daha iyi sunulur:

BigDecimal zero = BigDecimal.ZERO;

Bu, BigDecimal başlatma sırasında JVM tarafından önceden önbelleğe alındığı için tekrarlanan bir oluşturma maliyeti oluşmadan karşılaştırmalara izin verir.

Açıkladığınız şey söz konusu olduğunda, bir ilkel aynı işi yapmaktadır. Bu, önbellekleme ve performans açısından büyük ölçüde gereksizdir.

Adlandırma (olası değil)

Orijinal geliştirici, sistem genelinde ortak değerler için tek tip bir adlandırma kuralı sağlamaya çalışıyor. Bu, özellikle nadir değerler ile bazı değerlere sahiptir, ancak sıfır gibi temel bir şey, daha önce önbellekleme durumunda buna değer.

Zorlama türü (büyük olasılıkla)

Orijinal geliştirici, karşılaştırmaların doğru türlerine ve muhtemelen belirli bir ölçeğe (ondalık basamak sayısı) verilmesini sağlamak için belirli bir ilkel türü zorlamaya çalışıyor . Bu sorun değil, ancak "sıfır" basit adı, ZERO_1DP'nin niyetin daha uygun bir ifadesi olması nedeniyle bu kullanım durumu için muhtemelen yetersiz ayrıntıdır.


2
Zorlama türü için +1. Operatör aşırı yüklenmesine izin veren, sabit ve kullanımı tanımlayan C ++ gibi dillerde typedefdeğişkenin türünü tam olarak tek bir yerde tutacak ve kodu değiştirmek zorunda kalmadan değiştirmeyi sağlayacağım.
Blrfl

3
Zorlama türü büyük olasılıkla aradıkları şey değildir , ancak bu neden yapılabileceğinin en iyi açıklamasıdır !
NWS

7
Zorlama türü için, muhtemelen sadece kullanmayı tercih ederim 0.0f.
Svish

Zorlama türü, baytlarda bitsel işleçlerin gerçekleştirilmesinin bayt sonucu verdiği vb.net'te yararlı olabilir. Söylemek byteVar1 = byteVar2 Or CB128biraz daha hoş görünüyor byteVar1 = byteVar2 Or CByte(128). Tabii ki, baytlar için uygun bir sayısal sonek olması daha iyi olurdu. C # int, sonuçların sığacağı garanti edilse bile , işlenenleri operatörlere bitsel olarak desteklediğinden, bytesorun o kadar alakalı değildir.
supercat

'0' için sıfır olarak sabit bir adı olan emin değilim ama bazen kod okunabilirliği yardımcı olur; örneğin, bu sabitin sıfır olması - "ROOT_TYPE_ID = 0", if (id! = ROOT_TYPE_ID) {..}
Tech Junkie 16:

6

Çünkü "Takım Nagging"

Burada listelenmemiş görmemizin olası bir nedeni, birçok kaliteli aracın sihirli sayıların kullanımını işaretlemesidir . Sihirli rakamlara sahip olmak genellikle kötü bir uygulamadır kodların daha sonra değişiklik için açıkça görünür hale getirilmeden, özellikle de kodun birden çok yerinde çoğaltılmışsa, bir algoritmaya atılması .

Dolayısıyla, bu araçlar bu tür sorunları işaretlemek konusunda haklı olsalar da, genellikle yanlış pozitifler üretir bu değerlerin zararsız olduğu ve statik olma olasılığı yüksek olan durumlar için ya da sadece başlatma değerleri olması için .

Ve bu olduğunda, bazen aşağıdakilerle karşılaşırsınız:

  • araç izin veriyorsa bunları yanlış pozitif olarak işaretleme (genellikle aracı kullanmamış kişiler için rahatsız edici olan özel olarak biçimlendirilmiş bir yorum ile)
  • ya da bu değerleri önemli olsun ya da olmasın sabitlere çıkarmak.

Performans Hakkında

Sanırım dile bağlı, ancak bu Java'da oldukça yaygındır ve performans sabitliği yoktur, çünkü değerler gerçek sabitler ise derleme zamanında çizilir static final. Sabit veya hatta ön işlemci makroları olarak bildirildiklerinde C veya C ++ 'da bir etkisi olmaz.


5

Açıkça Zerotipte olduğunu tanımladığından bu mantıklı olabilirfloat .

En azından C ve C ++ 'da değer 0.0tip double, eşdeğer floatise 0.0f. Yani, xkıyasladığınız varsayılarak her zaman bir floatdeyiş

x > 0.0

aslında sorunlara yol açabilecek türlerle eşleşmeyi teşvik xeder (özellikle eşitlik testleriyle). Dönüşüm olmadan karşılaştırma elbettedouble0.0

x > 0.0f

aynı şeyi yapar

float Zero = 0.0; // double 0.0 converted to float  
x > Zero

Bununla birlikte, kullanıcıların garip kod yazması yerine derleyicideki dönüşüm uyarılarını etkinleştirmenin çok daha yararlı olacağını düşünüyorum.


1

Her şeyden önce, burada sıfır olarak tanımlanır float, değilint . Tabii ki, bu karşılaştırmadaki hiçbir şeyi etkilemez, ancak diğer durumlarda bu sabit kullanıldığında, fark yaratabilir.

ZeroBurada sabit kalmasının başka bir nedeni göremiyorum . Bu sadece bir kodlama stili ve belirli bir programda başka her yerde kullanılıyorsa stili takip etmek daha iyidir.


1

Yürütme sırasında neredeyse kesinlikle aynı derecede verimlidir (derleyiciniz çok ilkel değilse) ve derleme sırasında çok daha az verimlidir.

Bunun daha okunabilir olup olmadığı konusunda x > 0... dürüstçe, gerçekten, COBOL'un çalışmak için harika bir fikir ve zevk olduğunu düşünen insanlar olduğunu unutmayın - ve sonra C hakkında aynı şeyi düşünen insanlar var. hatta C ++ hakkında aynı görüşle bazı programcıları orada var olduğunu!) başka bir deyişle, sen edilir değil bu noktada genel anlaşma alacaksın, ve bitti muhtemelen değer kavga değil.


0

Bu gerçekten aşağıdakilerden daha verimli veya okunabilir veya bakım yapılabilir:

if (x > 0.0) {..}

Genel (yani türe özgü olmayan) bir kod yazıyorsanız , büyük olasılıkla. Bir zero()fonksiyon herhangi bir cebirsel tip veya grup wrt ilavesi olan herhangi bir tip için geçerli olabilir. Bir tamsayı olabilir, bir kayan nokta değeri olabilir, değişkeniniz, örneğin, kendisinin bir miktar doğrusal boşluk içindeki bir fonksiyon olması durumunda bile bir fonksiyon olabilir (örneğin x, z -> a_x * formunun doğrusal bir fonksiyonudur) z + b_x) ve ardından zero()işleve a ve b zero()altta yatan türde bir işlev sunar .

Yani, böyle bir kodu, örneğin, C ++ muhtemelen (a zero()çok yaygın bir AFAIK olmasa da ) veya Julia ve belki de diğer dillerde bekleyebilirsiniz .

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.