Bây giờ điều này phải dễ dàng, nhưng làm thế nào có thể tổng hai NSNumber
? Giống như:
[one floatValue] + [two floatValue]
hay tồn tại một cách tốt hơn?
Câu trả lời:
Thực sự không có cách nào tốt hơn, nhưng bạn thực sự không nên làm điều này nếu bạn có thể tránh nó. NSNumber
tồn tại như một trình bao bọc cho các số vô hướng để bạn có thể lưu trữ chúng trong các bộ sưu tập và chuyển chúng đa hình với các số khác NSObjects
. Chúng không thực sự được sử dụng để lưu trữ các con số trong toán học thực tế. Nếu bạn thực hiện phép toán trên chúng, nó sẽ chậm hơn nhiều so với việc thực hiện thao tác chỉ trên các đại lượng vô hướng, đó có thể là lý do tại sao không có phương pháp tiện lợi nào cho nó.
Ví dụ:
NSNumber *sum = [NSNumber numberWithFloat:([one floatValue] + [two floatValue])];
Đang thực hiện tối thiểu 21 hướng dẫn về việc gửi tin nhắn, và dù có nhiều mã thì các phương pháp thực hiện để mở hộp và hộp lại các giá trị (có thể là vài trăm) để thực hiện 1 lệnh toán học.
Vì vậy, nếu bạn cần lưu trữ số dưới dạng số, hãy sử dụng dấu NSNumber
, nếu bạn cần chuyển một thứ gì đó có thể là số hoặc chuỗi vào một hàm, hãy sử dụng dấu NSNumber
, nhưng nếu bạn chỉ muốn làm toán với các loại C vô hướng.
NSDecimalNumber (lớp con của NSNumber ) có tất cả các tính năng bạn đang tìm kiếm:
– decimalNumberByAdding:
– decimalNumberBySubtracting:
– decimalNumberByMultiplyingBy:
– decimalNumberByDividingBy:
– decimalNumberByRaisingToPower:
...
Nếu hiệu suất tính toán được quan tâm, thì hãy chuyển đổi sang mảng C ++ std :: vector hoặc tương tự.
Bây giờ tôi không bao giờ sử dụng C-Arrays nữa; quá dễ gặp sự cố khi sử dụng sai chỉ mục hoặc con trỏ. Và rất tẻ nhạt khi ghép mọi [] mới với xóa [].
NSDecimalNumber
s, làm thế nào để chuyển đổi NSDecimalNumber
kết quả trở lại NSNumber
? (Câu hỏi này là về việc thêm hai NSNumber
s chứ không phải thêm hai NSDecimalNumber
s.)
@interface NSDecimalNumber : NSNumber
Bạn có thể dùng
NSNumber *sum = @([first integerValue] + [second integerValue]);
Chỉnh sửa: Theo quan sát của ohho , ví dụ này là để cộng hai NSNumber
trường hợp chứa các giá trị số nguyên. Nếu bạn muốn cộng hai NSNumber
cái chứa giá trị dấu phẩy động, bạn nên làm như sau:
NSNumber *sum = @([first floatValue] + [second floatValue]);
int
hoặc long
hoặc đó là anh trai lớn typedef
'ed NSInteger
vào NSNumber
đối tượng .
integerValue
cắt bớt float
. Làm thế nào câu trả lời này có thể được bình chọn?
integerValue
nếu bạn muốn bảo toàn phần thập phân của các số?
Câu trả lời được bình chọn nhiều nhất hiện nay sẽ dẫn đến các lỗi khó chẩn đoán và mất độ chính xác do sử dụng phao nổi. Nếu bạn đang thực hiện các phép toán số trên các giá trị NSNumber, trước tiên bạn nên chuyển đổi thành NSDecimalNumber và thực hiện các thao tác với các đối tượng đó.
Từ tài liệu :
NSDecimalNumber, một lớp con bất biến của NSNumber, cung cấp một trình bao bọc hướng đối tượng để thực hiện số học cơ số 10. Một cá thể có thể đại diện cho bất kỳ số nào có thể được biểu thị dưới dạng số mũ định trị x 10 ^ trong đó phần định trị là số nguyên thập phân dài tối đa 38 chữ số và số mũ là số nguyên từ –128 đến 127.
Do đó, bạn nên chuyển đổi các phiên bản NSNumber của mình thành NSDecimalNumbers bằng cách [NSNumber decimalValue]
thực hiện bất kỳ số học nào bạn muốn, sau đó gán lại cho NSNumber khi bạn hoàn tất.
Trong Objective-C:
NSDecimalNumber *a = [NSDecimalNumber decimalNumberWithDecimal:one.decimalValue]
NSDecimalNumber *b = [NSDecimalNumber decimalNumberWithDecimal:two.decimalValue]
NSNumber *result = [a decimalNumberByAdding:b]
Trong Swift 3:
let a = NSDecimalNumber(decimal: one.decimalValue)
let b = NSDecimalNumber(decimal: two.decimalValue)
let result: NSNumber = a.adding(b)
Tại sao không sử dụng NSxEpression
?
NSNumber *x = @(4.5), *y = @(-2);
NSExpression *ex = [NSExpression expressionWithFormat:@"(%@ + %@)", x, y];
NSNumber *result = [ex expressionValueWithObject:nil context:nil];
NSLog(@"%@",result); // will print out "2.5"
Bạn cũng có thể xây dựng một NSExpression có thể được sử dụng lại để đánh giá với các đối số khác nhau, như sau:
NSExpression *expr = [NSExpression expressionWithFormat: @"(X+Y)"];
NSDictionary *parameters = [NSDictionary dictionaryWithObjectsAndKeys:x, @"X", y, @"Y", nil];
NSLog(@"%@", [expr expressionValueWithObject:parameters context:nil]);
Ví dụ: chúng ta có thể lặp lại đánh giá cùng một biểu thức được phân tích cú pháp, mỗi lần với một giá trị "Y" khác nhau:
for (float f=20; f<30; f+=2.0) {
NSDictionary *parameters = [NSDictionary dictionaryWithObjectsAndKeys:x, @"X", @(f), @"Y", nil];
NSLog(@"%@", [expr expressionValueWithObject:parameters context:nil]);
}
Trong Swift, bạn có thể có được chức năng này bằng cách sử dụng thư viện Bolt_Swift https://github.com/williamFalcon/Bolt_Swift .
Thí dụ:
var num1 = NSNumber(integer: 20)
var num2 = NSNumber(integer: 25)
print(num1+num2) //prints 45