Numaradan sonra "f"


102

fNumaralardan sonra ne ifade ediyor ? Bu C'den mi yoksa Amaç-C'den mi? Bunu sabit bir sayıya eklememek arasında bir fark var mı?

CGRect frame = CGRectMake(0.0f, 0.0f, 320.0f, 50.0f);

Neden sadece yazmadığımı açıklayabilir misin:

CGRect frame = CGRectMake(0, 0, 320, 50);

Yanıtlar:


88
CGRect frame = CGRectMake(0.0f, 0.0f, 320.0f, 50.0f);

float sabitleri kullanır. (0.0 sabiti genellikle Amaç-C'de bir double bildirir; sona bir f koymak - 0.0f - sabiti (32-bit) kayan nokta olarak ilan eder.)

CGRect frame = CGRectMake(0, 0, 320, 50);

otomatik olarak kayan sayılara dönüştürülecek olan ints kullanır.

Bu durumda ikisi arasında (pratik) bir fark yoktur.


24
Teorik olarak, derleyici onları derleme zamanında float olacak şekilde dönüştürmek için yeterince akıllı olmayabilir ve dört int-> float dönüşümü (en yavaş yayınlar arasında olan) ile yürütmeyi yavaşlatabilir. Bu durumda neredeyse önemsiz olsa da, gerekirse f'yi doğru olarak belirtmek her zaman daha iyidir: bir ifadede doğru belirticiye sahip olmayan bir sabit, tüm ifadeyi ikiye katlamaya zorlayabilir ve sıkı bir döngüdeyse performans vuruşu olabilir farkedilebilir.
Matteo Italia

60

Şüphe duyduğunuzda montajcı çıktısını kontrol edin. Örneğin küçük, minimal bir pasaj yazın, yani bunun gibi

#import <Cocoa/Cocoa.h>

void test() {
  CGRect r = CGRectMake(0.0f, 0.0f, 320.0f, 50.0f);
  NSLog(@"%f", r.size.width);
}

Daha sonra bunu -Sseçeneği ile assembler'a derleyin .

gcc -S test.m

Assembler çıktısını test.sdosyaya kaydedin ve .0fsabitlerden kaldırın ve derleme komutunu tekrarlayın. Sonra bunu diffyeni test.sve öncekinden. Bunun gerçek farklılıklar olup olmadığını göstermesi gerektiğini düşünün. Bence pek çok kişinin derleyicinin ne yaptığını düşündüklerine dair bir vizyonu var, ancak günün sonunda herhangi bir teoriyi nasıl doğrulayacağını bilmek gerekiyor.


11
Çıktı benim için hiç olmasa bile aynı çıktı -O. I'm on i686-apple-darwin10-gcc-4.2.1 (GCC)
kizzx2

2
Yukarıdaki örneği LLVM 7.0.0 (clang-700.0.65) x86_64-apple-darwin15.0.0 ile denedim ve .out dosyaları da aynıydı.
Nick

43

Bazen bir fark vardır.

float f = 0.3; /* OK, throw away bits to convert 0.3 from double to float */
assert ( f == 0.3 ); /* not OK, f is converted from float to double
   and the value of 0.3 depends on how many bits you use to represent it. */
assert ( f == 0.3f ); /* OK, comparing two floats, although == is finicky. */

26

Bilgisayara bunun bir kayan nokta numarası olduğunu söyler (burada c / c ++ hakkında konuştuğunuzu varsayıyorum). Sayıdan sonra f yoksa, çift veya tam sayı olarak kabul edilir (ondalık olup olmadığına bağlı olarak).

3.0f -> float
3.0 -> double
3 -> integer

bu kural C ++ standardının bir parçası mı yoksa derleyicide mi bulunuyor?
jxramos

1
Anladığım kadarıyla standardın bir parçası (yanılıyorsam birisi beni düzeltir). Bulabildiğim en hızlı referans open-std.org/jtc1/sc22/open/n2356/lex.html#lex.fcon'dur , ancak aramak isterseniz muhtemelen daha güncel referanslar vardır.
NickLH

5

Kaynak kodunuzdaki bir kayan nokta değişmezi bir double olarak ayrıştırılır. Float türünde bir değişkene atamak hassasiyeti kaybeder. Çok fazla hassasiyet, 7 önemli basamağı atıyorsunuz. "F" soneki derleyiciye şunu söyleyelim: "Ne yaptığımı biliyorum, bu kasıtlı. Beni bu konuda rahatsız etmeyin".

Bir hata üretme olasılığı o kadar küçük değil. Pek çok program, yanlış tasarlanmış bir kayan nokta karşılaştırmasına ya da 0.1'in tam olarak gösterilebilir olduğunu varsaydı.


4

fBahsediyorsun muhtemelen bir şamandıra ile çalışıyor o derleyici anlatmak amaçlı olduğunu. Atladığınızda f, genellikle bir çift olarak çevrilir.

Her ikisi de kayan nokta sayılarıdır, ancak a, floata'dan daha az bit kullanır (dolayısıyla daha küçük ve daha az hassas) double.


3

Bu bir C meselesi - kayan nokta değişmezleri varsayılan olarak çift duyarlıklıdır (çift). Bir f son eki eklemek onları tek duyarlıklı (kayan nokta) yapar.

Burada değerleri belirtmek için ints kullanabilirsiniz ve bu durumda hiçbir fark yaratmaz, ancak doğru türü kullanmak iyi bir alışkanlıktır - tutarlılık genel olarak iyi bir şeydir ve bu değerleri daha sonra değiştirmeniz gerekirse Ne tür olduklarını ilk bakışta anlayacağım.


2

C'den float değişmez sabit anlamına gelir. İnts'in yüzen sayılara örtük dönüşümü nedeniyle, örneğinizde hem "f" hem de ".0" i atlayabilir ve ints kullanabilirsiniz.


1

Neredeyse kesinlikle C'den geliyor ve 'çift' tip yerine 'kayan nokta' kullanma arzusunu yansıtıyor. Uzun tam sayı olduklarını belirtmek için sayıların üzerindeki L gibi son eklere benzer. Tam sayıları kullanabilirsiniz ve derleyici uygun şekilde otomatik olarak dönüştürecektir (bu özel senaryo için).


0

Genellikle derleyiciye değerin a float, yani bir kayan noktalı tamsayı olduğunu söyler . Bu, tam sayıları, ondalık değerleri ve üslü sayıları depolayabileceği anlamına gelir, örn. 1, 0.4Veya 1.2e+22.

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.