"F" setelah nomor


102

Apa fyang ditunjukkan setelah angka? Apakah ini dari C atau Objective-C? Apakah ada perbedaan dalam tidak menambahkan ini ke bilangan konstan?

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

Bisakah Anda menjelaskan mengapa saya tidak menulis:

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

Jawaban:


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

menggunakan konstanta float. (Konstanta 0.0 biasanya mendeklarasikan double di Objective-C; meletakkan f di ujung - 0.0f - mendeklarasikan konstanta sebagai float (32-bit).)

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

menggunakan int yang akan secara otomatis diubah menjadi float.

Dalam hal ini, tidak ada perbedaan (praktis) di antara keduanya.


24
Secara teoritis, kompilator mungkin tidak cukup pintar untuk mengubahnya menjadi float pada waktu kompilasi, dan akan memperlambat eksekusi dengan empat konversi int-> float (yang termasuk di antara cast paling lambat). Meskipun dalam kasus ini hampir tidak penting, itu selalu lebih baik untuk menentukan dengan benar f jika diperlukan: dalam sebuah ekspresi sebuah konstanta tanpa penentu yang tepat dapat memaksa seluruh ekspresi untuk diubah menjadi ganda, dan jika berada dalam loop yang ketat kinerja hit mungkin nyata.
Matteo Italia

60

Jika ragu, periksa keluaran assembler. Misalnya tulis potongan kecil, minimal seperti ini

#import <Cocoa/Cocoa.h>

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

Kemudian kompilasi ke assembler dengan -Sopsi.

gcc -S test.m

Simpan keluaran assembler dalam test.sfile dan hapus .0fdari konstanta dan ulangi perintah kompilasi. Kemudian lakukan diffyang baru test.sdan yang sebelumnya. Pikirkan itu harus menunjukkan jika ada perbedaan nyata. Saya pikir terlalu banyak yang memiliki visi tentang apa yang menurut mereka dilakukan oleh kompilator, tetapi pada akhirnya orang harus tahu cara memverifikasi teori apa pun.


11
Outputnya ternyata identik untuk saya, bahkan tanpa apapun -O. Saya menggunakan i686-apple-darwin10-gcc-4.2.1 (GCC)
kizzx2

2
Saya mencoba contoh di atas dengan LLVM versi 7.0.0 (clang-700.0.65) x86_64-apple-darwin15.0.0 dan file .out juga identik.
Nick

43

Terkadang ada perbedaan.

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

Ini memberi tahu komputer bahwa ini adalah bilangan floating point (saya asumsikan Anda berbicara tentang c / c ++ di sini). Jika tidak ada f setelah bilangan, itu dianggap ganda atau bilangan bulat (tergantung apakah ada desimal atau tidak).

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

apakah konvensi ini bagian dari standar C ++ atau ada di compiler?
jxramos

1
Sejauh yang saya tahu itu adalah bagian dari standar (seseorang mengoreksi saya jika saya salah). Referensi tercepat yang dapat saya temukan adalah open-std.org/jtc1/sc22/open/n2356/lex.html#lex.fcon , tetapi mungkin ada lebih banyak referensi terbaru jika Anda ingin mencarinya.
NickLH

5

Literal floating point dalam kode sumber Anda diuraikan sebagai ganda. Menetapkannya ke variabel berjenis float akan kehilangan presisi. Sangat presisi, Anda membuang 7 digit signifikan. Postfix "f" memberi tahu compiler: "Saya tahu apa yang saya lakukan, ini disengaja. Jangan mengganggu saya".

Kemungkinan menghasilkan bug tidaklah kecil. Banyak program telah jatuh ke atas pada perbandingan floating point yang salah dipahami atau mengasumsikan bahwa 0,1 benar-benar dapat direpresentasikan.


4

Yang fAnda bicarakan mungkin dimaksudkan untuk memberi tahu kompiler bahwa ia bekerja dengan float. Saat Anda menghilangkanf , biasanya diterjemahkan menjadi ganda.

Keduanya adalah bilangan floating point, tetapi floatmenggunakan lebih sedikit bit (sehingga lebih kecil dan kurang tepat) daripada a double.


3

Ini adalah hal C - literal floating point presisi ganda (ganda) secara default. Menambahkan sufiks f membuatnya menjadi presisi tunggal (mengambang).

Anda dapat menggunakan int untuk menentukan nilai di sini dan dalam hal ini tidak akan ada bedanya, tetapi menggunakan jenis yang benar adalah kebiasaan yang baik untuk diterapkan - konsistensi adalah hal yang baik secara umum, dan jika Anda perlu mengubah nilai ini nanti Anda Sekilas akan tahu apa tipe mereka.


2

Dari C. Ini berarti konstanta literal float. Anda dapat menghilangkan "f" dan ".0" dan menggunakan int dalam contoh Anda karena konversi implisit dari int menjadi float.


1

Ini hampir pasti dari C dan mencerminkan keinginan untuk menggunakan tipe 'float' daripada 'double'. Ini mirip dengan sufiks seperti L pada angka untuk menunjukkan bahwa mereka adalah bilangan bulat panjang. Anda bisa menggunakan integer dan kompilator akan otomatis mengkonversi sesuai (untuk skenario khusus ini).


0

Ini biasanya memberitahu compiler bahwa nilainya adalah a float, yaitu integer floating point. Ini berarti dapat menyimpan bilangan bulat, nilai desimal dan eksponensial, misalnya 1, 0.4atau 1.2e+22.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.