tôi làm việc chủ yếu với số nguyên trước đây, và trong những tình huống mà tôi cần phải cắt xén một float hay double thành một số nguyên, tôi sẽ sử dụng sau đây trước:Trong C và Objective-C, những gì thực sự là đúng cách để cắt ngắn một phao hoặc đôi để một số nguyên?
(int) someValue
trừ cho đến khi tôi phát hiện ra những điều sau đây:
NSLog(@"%i", (int) ((1.2 - 1) * 10)); // prints 1
NSLog(@"%i", (int) ((1.2f - 1) * 10)); // prints 2
(vui lòng xem Strange behavior when casting a float to int in C# để được giải thích).
Câu hỏi ngắn gọn là: cách chúng tôi nên cắt ngắn một phao hoặc gấp đôi thành số nguyên đúng cách? (Truncation là muốn trong trường hợp này, không phải "làm tròn"). Hoặc, chúng tôi có thể nói rằng vì một số là 1.9999999999999 và số kia là 2.00000000000001 (nói gần), truncate thực sự được thực hiện chính xác. Vì vậy, câu hỏi là, làm thế nào chúng ta nên chuyển đổi một phao hoặc tăng gấp đôi để kết quả là một số "cắt ngắn" mà làm cho cảm giác sử dụng phổ biến?
(mục đích không phải là để sử dụng round
, bởi vì trong trường hợp này, cho 1.8
, chúng tôi muốn kết quả của 1
, thay vì 2
) câu hỏi
dài:
tôi đã sử dụng
int truncateToInteger(double a) {
return (int) (a + 0.000000000001);
}
-(void) someTest {
NSLog(@"%i", truncateToInteger((1.2 - 1) * 10));
NSLog(@"%i", truncateToInteger((1.2f - 1) * 10));
}
và cả hai in ra là 2
, nhưng có vẻ như quá nhiều hack và những gì số lượng nhỏ chúng ta nên sử dụng để "loại bỏ sự thiếu chính xác"? Có một cách tiêu chuẩn hay được nghiên cứu hơn, thay vì hack tùy ý như vậy?
(Lưu ý rằng chúng tôi muốn cắt bớt, không làm tròn trong một số cách sử dụng, ví dụ: nếu số giây là 90 hoặc 118, khi chúng tôi hiển thị số phút và số giây đã trôi qua, phút sẽ hiển thị dưới dạng 1
, nhưng không được làm tròn lên đến 2
)
Chức năng 'sàn' có cùng vấn đề không? – Scroog1
có, tầng có cùng vấn đề (đầu tiên sử dụng sàn và sau đó truyền tới int) –
khá là bất tiện: ( – Scroog1