"F" sau số


102

Làm gì fsau những con số cho thấy? Đây là từ C hay Objective-C? Có sự khác biệt nào khi không thêm số này vào một số không đổi?

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

Bạn có thể giải thích tại sao tôi không viết:

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

Câu trả lời:


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

sử dụng hằng số float. (Hằng số 0.0 thường khai báo một số kép trong Objective-C; đặt một f ở cuối - 0.0f - khai báo hằng số dưới dạng float (32-bit).)

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

sử dụng ints sẽ được tự động chuyển đổi thành float.

Trong trường hợp này, không có sự khác biệt (thực tế) giữa hai.


24
Về mặt lý thuyết, trình biên dịch có thể không đủ thông minh để chuyển đổi chúng thành float tại thời điểm biên dịch và sẽ làm chậm quá trình thực thi với bốn lần chuyển đổi int-> float (nằm trong số những lần chuyển đổi chậm nhất). Mặc dù trong trường hợp này hầu như không quan trọng, nhưng tốt hơn hết là chỉ định chính xác f nếu cần: trong một biểu thức, một hằng số không có từ xác định phù hợp có thể buộc toàn bộ biểu thức được chuyển đổi thành gấp đôi và nếu nó ở trong một vòng lặp chặt chẽ, lần truy cập hiệu suất có thể là đáng chú ý.
Matteo Italia

60

Khi nghi ngờ, hãy kiểm tra đầu ra của trình lắp ráp. Ví dụ: viết một đoạn mã nhỏ, tối thiểu, tức là như thế này

#import <Cocoa/Cocoa.h>

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

Sau đó, biên dịch nó sang trình hợp ngữ với -Stùy chọn.

gcc -S test.m

Lưu đầu ra của trình hợp dịch trong test.stệp và xóa .0fkhỏi các hằng số và lặp lại lệnh biên dịch. Sau đó, thực hiện một difftrong số mới test.svà trước đó. Hãy nghĩ rằng điều đó sẽ cho thấy nếu có bất kỳ sự khác biệt thực sự nào. Tôi nghĩ rằng quá nhiều người có tầm nhìn về những gì họ nghĩ rằng trình biên dịch làm, nhưng vào cuối ngày, người ta nên biết cách xác minh bất kỳ lý thuyết nào.


11
Đầu ra hóa ra là giống hệt nhau đối với tôi, thậm chí không có bất kỳ -O. Tôi đang trên i686-apple-darwin10-gcc-4.2.1 (GCC)
kizzx2

2
Tôi đã thử ví dụ trên với phiên bản LLVM 7.0.0 (clang-700.0.65) x86_64-apple-darwin15.0.0 và các tệp .out cũng giống hệt nhau.
Nick

43

Đôi khi có sự khác biệt.

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

Nó cho máy tính biết rằng đây là một số dấu phẩy động (tôi giả sử bạn đang nói về c / c ++ ở đây). Nếu không có f sau số, nó được coi là một đôi hoặc một số nguyên (tùy thuộc vào việc có số thập phân hay không).

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

quy ước này là một phần của tiêu chuẩn C ++ hay nó được tìm thấy trong trình biên dịch?
jxramos

1
Theo như tôi có thể nói nó là một phần của tiêu chuẩn (ai đó sẽ sửa cho tôi nếu tôi sai). Tài liệu tham khảo nhanh nhất mà tôi có thể tìm thấy là open-std.org/jtc1/sc22/open/n2356/lex.html#lex.fcon , nhưng có lẽ có nhiều tài liệu tham khảo cập nhật hơn nếu bạn muốn tìm kiếm chúng.
NickLH

5

Một ký tự dấu phẩy động trong mã nguồn của bạn được phân tích cú pháp kép. Gán nó cho một biến có kiểu float sẽ làm mất độ chính xác. Chính xác rất nhiều, bạn đang bỏ đi 7 chữ số có nghĩa. Hậu tố "f" cho phép bạn nói với trình biên dịch: "Tôi biết tôi đang làm gì, điều này là cố ý. Đừng khiến tôi khó chịu về điều đó".

Tỷ lệ tạo ra một lỗi không phải là nhỏ. Nhiều chương trình đã tập trung vào một phép so sánh dấu phẩy động không hợp lý hoặc giả định rằng 0,1 là có thể biểu diễn chính xác.


4

Cái fmà bạn đang nói đến có thể là để nói với trình biên dịch rằng nó đang hoạt động với một float. Khi bạn bỏ qua f, nó thường được dịch thành dấu kép.

Cả hai đều là số dấu phẩy động, nhưng a floatsử dụng ít bit hơn (do đó nhỏ hơn và kém chính xác hơn) so với a double.


3

Đó là một điều C - các ký tự dấu phẩy động có độ chính xác kép (gấp đôi) theo mặc định. Thêm một hậu tố f làm cho chúng có độ chính xác đơn (float).

Bạn có thể sử dụng int để chỉ định các giá trị ở đây và trong trường hợp này, nó sẽ không có gì khác biệt, nhưng sử dụng đúng loại là một thói quen tốt để thực hiện - nói chung nhất quán là một điều tốt và nếu bạn cần thay đổi các giá trị này sau đó, bạn Thoạt nhìn sẽ biết chúng thuộc loại nào.


2

Từ C. Nó có nghĩa là hằng số float. Bạn có thể bỏ qua cả "f" và ".0" và sử dụng int trong ví dụ của mình vì chuyển đổi ngầm định int thành float.


1

Nó gần như chắc chắn là từ C và phản ánh mong muốn sử dụng kiểu 'float' thay vì kiểu 'double'. Nó tương tự như các hậu tố như L trên các số để chỉ ra chúng là các số nguyên dài. Bạn chỉ có thể sử dụng số nguyên và trình biên dịch sẽ tự động chuyển đổi khi thích hợp (đối với trường hợp cụ thể này).


0

Nó thường cho trình biên dịch biết rằng giá trị là a float, tức là một số nguyên dấu phẩy động. Điều này có nghĩa rằng nó có thể lưu trữ các số nguyên, giá trị thập phân và hàm mũ, ví dụ 1, 0.4hoặc 1.2e+22.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.