我有一个NSMutableArray
其中有一些NSDecimalNumber
在里面,像(500,50.80,70,8000)
现在我想所有这些加decimal numbers
在一起。
我试着使用
for (NSDecimalNumber *number in self.numbersArray)
{
NSDecimal *sum += [number decimalValue]
}
但是失败了。
我有一个NSMutableArray
其中有一些NSDecimalNumber
在里面,像(500,50.80,70,8000)
现在我想所有这些加decimal numbers
在一起。
我试着使用
for (NSDecimalNumber *number in self.numbersArray)
{
NSDecimal *sum += [number decimalValue]
}
但是失败了。
使用- (NSDecimalNumber *)decimalNumberByAdding:(NSDecimalNumber *)decimalNumber
看看NSDecimalNumber类参考
NSDecimalNumber *lNumber = [NSDecimalNumber zero];
for (NSDecimalNumber *number in self.numbersArray)
{
lNumber = [lNumber decimalNumberByAdding:number];
}
一个简单的方法来添加所有NSNumber
S IN的阵列(类似于@Mahonor在注释中说的):
NSArray *myArray = ... // array of NSNumber (or NSDecimalNumber) objects
NSNumber *sum = [myArray valueForKeyPath:@"@sum.self"];
相反的是,在收集运营商:和美国,数字数组中不被转换为double
,但NSDecimal
。 因此,加入十进制数字时, 没有精度丢失 。 即使NSNumber
这不是小数对象转换为NSDecimal
的加法。 求和的结果是实例NSDecimalValue
。
我验证(或尝试),在两种不同的方式。 首先,我跑这个代码
NSNumber *a = [NSNumber numberWithDouble:1.2];
NSNumber *b = [NSDecimalNumber decimalNumberWithString:@"-5.7"];
NSArray *myArray = @[a, b];
id sum = [myArray valueForKeyPath:@"@sum.self"];
并且通过设置环境变量“NSObjCMessageLoggingEnabled = YES”活化Objective-C的消息记录。 如可在所创建的“/ TMP / msgSends-NNNN”文件中可以看出, decimalNumber
(而不是doubleValue
)被发送到这两个数量的对象。
第二,我创建实现两者的自定义类decimalValue
和doubleValue
,并应用于@sum.self
到自定义类的对象的数组:
@interface MyClass : NSObject
@property (nonatomic, assign) double value;
@end
@implementation MyClass
- (NSDecimal)decimalValue
{
return [[NSNumber numberWithDouble:self.value] decimalValue];
}
- (double)doubleValue
{
return self.value;
}
@end
MyClass *a = [MyClass new]; a.value = 1.2;
MyClass *b = [MyClass new]; b.value = -5.7;
NSArray *myArray = @[a, b];
id sum = [myArray valueForKeyPath:@"@sum.self"];
通过设置在两种方法中的断点,可以看出,仅decimalValue
用于概括( valueForKeyPath:@"@sum.self"
抛出一个异常,如果类未实现decimalValue
)。
人们还可以看到, decimalValue
从所谓
-[NSArray(NSKeyValueCoding) _sumForKeyPath:]
和用于该方法的汇编代码显示NSDecimalAdd
是使用添加的号码。
马诺哈尔的在评论中建议也不错。 事实上,你可以使用KVC收集运营商做一个班轮出这一点: [myArray valueForKeyPath:@"@sum.doubleValue"];
,但你可能会失去精度(取决于您所储存的号码)。
你基本上是寻找“减少”的功能; 你需要链调用decimalNumberByAdding:
这样每次调用具有阵列作为参数的成功元素。 在一个这样做NSArray
是很容易的,使用performSelector:withObject:
@implementation NSArray (Reduce)
- (id)reduceUsingSelector: (SEL)sel
{
id res = [self objectAtIndex:0];
for( id obj in [self subarrayWithRange:(NSRange){1, [self count]-1}] ){
res = [res performSelector:sel withObject:obj];
}
return res;
}
@end
使用此像这样: NSDecimalNumber * sum = [myArray reduceUsingSelector:@selector(decimalNumberByAdding:)];
你的代码是不是成功,因为NSDecimal
是一个结构,而不是一个对象; 它不应该被声明为指针,如果不是这样,你就不能添加。 这不是一个解决方案正确的路线。