2013-08-05 87 views
23

Tôi có mộtiOS Objective-C Làm thế nào để có được 2 giá trị phẩy tròn thập phân?

float a = 1412.244019; 

và tôi cần một để được làm tròn đến chữ số thập phân thứ hai gần như 1412,24000000. Tôi hiểu rằng nếu tôi muốn trình bày một chỉ với hai số thập phân tôi sử dụng% .2f, nhưng đó không phải là trường hợp. Tôi cần một lý do toán học mới như một phao.

Tôi đã thử một vài phương pháp được tìm thấy trên stackoverflow mà không có may mắn. Cái tôi thấy rõ ràng hơn, tôi đề cập bên dưới, nhưng vẫn không có may mắn khi sử dụng nó. Bạn có thể thấy tại sao phép thuật không xảy ra?

PS: Nó có tác dụng mong muốn đôi khi, KHÔNG phải lúc nào cũng khiến tôi suy nghĩ ... hmmm ...

Xin cảm ơn trước.

Code:

float a = 1412.244019; 
NSLog(@"a is %f", a); //output a is 1412.244019 
a = [[NSString stringWithFormat:@"%.2f", a] floatValue]; 
NSLog(@"a is %f", a); //output a is 1412.239990 

EDIT:

có vẻ như khi tôi đang sử dụng các phao một sau khi phẫu thuật trên, nó đang xem xét nó được 1412,240000 eventhough NSLog nói cách khác nhau ... lạ. Nhưng tôi đang nhận được những gì tôi muốn, vì vậy Kudos cho thời gian lãng phí đuổi gì :)

EDIT Tôi rất thích để lựa chọn cho bạn tất cả câu trả lời là đúng, nhưng kể từ khi tôi chỉ có thể chọn một, tôi đã chọn câu trả lời tốt đầu tiên với lời giải thích thêm (của hai người cuối cùng).

Trả lời

49

Bạn đã thử điều này chưa?

CGFloat val = 37.777779; 

CGFloat rounded_down = floorf(val * 100)/100; /* Result: 37.77 */ 
CGFloat nearest = floorf(val * 100 + 0.5)/100; /* Result: 37.78 */ 
CGFloat rounded_up = ceilf(val * 100)/100;  /* Result: 37.78 */ 

nguồn: Rounding Number to 2 Decimal Places in C

bổ sung: Bạn chỉ cần không có quyền kiểm soát về cách máy tính sẽ lưu trữ các giá trị float.

Vì vậy, các giá trị được làm tròn này có thể không chính xác "giá trị thập phân" rõ ràng, nhưng chúng sẽ rất gần và đó là đảm bảo tối đa bạn sẽ có.

+0

Đã thử nó, Saw bạn đã đăng phương pháp này trong bài đăng khác. Nhưng NSLog vẫn cho cùng một câu trả lời (thử bản thân). Nhưng vui lòng xem EDIT ở trên. Mặc dù NSLog đang đưa ra định dạng "sai", nó đang sử dụng nó đúng. –

+0

Giống như tôi đã nói trong bản chỉnh sửa, không thể có được độ chính xác đầy đủ trong các điểm nổi –

+0

Tôi hiểu. Nó đang tính toán theo cách tôi muốn. Tôi chỉ nghĩ điều đó thật kỳ lạ, bởi vì thế thì bạn sẽ không bao giờ có thể sử dụng số học chính xác? –

2

Bạn có thể nhân với 100.0 và có thể thêm 0,5 để làm tròn và sau đó lấy giá trị int của kết quả. Sau đó, bạn có thể sử dụng/100 để lấy giá trị trước dấu thập phân và% 100 để lấy hai chữ số thập phân.

+0

tôi đã cố gắng để làm điều đó không có may mắn. Xem sửa đổi ở trên (đến trong hai phút) –

2

Bạn không thể ép buộc giá trị nổi. Nổi được thiết kế để có phần gần đúng, vì độ lớn của chúng có thể rất lớn và vì bạn chỉ có nhiều bit để sử dụng, nên nó có thể gần đến, nhưng không thể hiện chính xác số thập phân.

Một đề xuất là thực hiện tất cả số học của bạn bằng số nguyên, nhân với 100, sau đó chia khi bạn muốn hiển thị kết quả cuối cùng của mình. Bạn có thể có số lượng quá lớn sẽ cấm điều này.

+0

Tôi appreaciate câu trả lời của bạn, và tôi nghĩ rằng tôi sẽ phải tìm một cách khác. Nhưng vui lòng xem EDIT ở trên. Mặc dù NSLog đang đưa ra định dạng "sai", nó đang sử dụng nó đúng. –

+0

NSLog đang nói cho bạn sự thật ... nhưng có thể bạn đang sử dụng định dạng/số học khác đang cân bằng (như số học nổi được thiết kế để làm) để giúp bạn gần câu trả lời đúng. Nhưng bạn sẽ thấy rằng đôi khi nó làm những gì bạn mong đợi, và đôi khi nó có những dấu thập phân sau đó không nên có, hoặc số lượng chỉ là ngắn. Điều này rõ ràng nhất khi bạn in câu trả lời hoặc nếu bạn cố so sánh hai số dấu phẩy động (tức là 2.0! = 5.0 - 3.0). Nếu bạn cần số học chính xác, luôn luôn đúng với 2 chữ số thập phân, bạn nên sử dụng số nguyên như trên và/100. –

5

Giá trị gần nhất với 1412.24 là float có thể có là 1412.239990234375. Có không hoạt động có thể tạo ra float bất kỳ điều gì gần hơn thế, vì định dạng của float đối tượng không đại diện cho bất kỳ giá trị nào gần hơn. Yêu cầu đại diện cho 1412.24 theo số float giống như yêu cầu đại diện cho 2.5 trong số int. Nó chỉ đơn giản là không thể được thực hiện.

Tùy chọn để đối phó với điều này bao gồm:

  • Bạn có thể sử dụng định dạng sử dụng có hiển thị “1412,24”, mà không thay đổi cơ bản float đối tượng.
  • Bạn có thể sử dụng double để đến gần hơn (gần hơn), nhưng nó vẫn sẽ không chính xác là 1412,24.
  • Bạn có thể chia tỷ lệ float giá trị thành các giá trị có thể biểu diễn (ví dụ: đo lường trong các đơn vị khác để các giá trị bạn muốn đều chính xác được thể hiện trong float).
  • Bạn có thể sử dụng loại dữ liệu khác, chẳng hạn như NSDecimal.
+0

Tôi appreaciate câu trả lời của bạn, và tôi nghĩ rằng tôi sẽ phải tìm một cách khác. Nhưng vui lòng xem EDIT ở trên.Mặc dù NSLog đang đưa ra định dạng "sai", nó đang sử dụng nó đúng. Tôi sẽ thấy nếu tôi nhận được kết quả tốt hơn bằng cách sử dụng một trong các phương pháp được đề cập ở trên của bạn. –

+1

@ B-Man, loại C 'float' KHÔNG THỂ hứa hẹn làm tròn hoàn hảo. Nếu bạn yêu cầu điều đó, hãy sử dụng một kiểu dữ liệu khác. Bạn có thể cuộn riêng của bạn và giữ giá trị trong giá trị NSInteger của 100th, hoặc bạn có thể sử dụng một kiểu dữ liệu khác như [NSDecimal] (https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation /Classes/NSDecimalNumber_Class/Reference/Reference.html) được liệt kê ở trên. – bshirley

10

Bạn làm điều đó trong Objective-C giống hệt nhau như bạn làm trong C:

double notRounded = ...; 
double rounded = round (notRounded * 100.0)/100.0; 

Không sử dụng phao - trừ khi bạn có thể giải thích cho một người nào đó chính xác những gì lý do cụ thể của bạn là sử dụng phao hơn gấp đôi. float có độ chính xác rất hạn chế. Và sử dụng ceil hoặc sàn là daft, vì có một chức năng tiêu chuẩn hoàn hảo tốt có tên là "tròn".

Không phao hoặc đôi có thể chính xác đại diện cho hầu hết các giá trị thập phân, như 12,24. Bởi vì nó có độ chính xác cao hơn nhiều, gấp đôi sẽ cho phép bạn tiến gần hơn đến 12,24. Vì vậy, có một cơ hội rất lớn mà NSLog sẽ hiển thị một số số lạ cho (float) 12,24, như 12.23999997394 hoặc bất cứ điều gì, trong khi nó có thể hiển thị 12,24 cho đôi.

+1

Cảm ơn câu trả lời. Double là con đường để đi sau đó. Tôi đã chọn một câu trả lời một số thời gian trước đây, vì vậy tôi nghĩ rằng tôi chỉ có thể trả lời của bạn. Cảm ơn thời gian của bạn để giải thích, nhiều đánh giá cao. –

1

Lỗi trong dòng này

a = [[NSString stringWithFormat:@"%.2f", a] floatValue]; 

đúng nó để

a = [NSString stringWithFormat:@"%.02f", a]; 
Các vấn đề liên quan