我遇到了decimalNumberBySubtracting和decimalNumberByDividingBy的问题

时间:2010-02-01 19:01:06

标签: objective-c cocoa nsdecimalnumber

简单地说,decimalNumberBySubtractingdecimalNumberByDividingBy根本不起作用......没有错误,只是搞砸了结果。我真的需要解决这个问题,但我没有得到任何错误,我无法想到如何进行计算的任何其他方式!我得到的数字如下:

  

257849691392950000000000000000000000000000000000000000000000000000000000000000000

他们应该在哪里评估:

  

-0.581

这是长篇故事。我正在尝试对数据集进行简单的Z-Score计算。 Zscore定义为(X - Average)/(stdDev)。很简单。我的测试数据包括5个板,每个板有96个样品。该代码识别每个单独的板,为每个板生成平均值和stdev,然后对于THAT板中的每个样品,执行上述计算。

//identify unique plates
NSSet * uniqueValues = [NSSet setWithArray:[items valueForKey:@"plate"]];
id i;
for (i in uniqueValues) {
    //Lots of NSExpression and Predicate stuff I pulled out cause its working fine

    NSExpression *plateMeanExpression = [NSExpression expressionForFunction:@"average:"
                                                                  arguments:plateArgumentArray];
    NSExpression *plateStdDevExpression = [NSExpression expressionForFunction:@"stddev:"
                                                                    arguments:plateArgumentArray];

    // generate Z Score and StDev:
    NSDecimalNumber *zscoreMean = [plateMeanExpression expressionValueWithObject:nil
                                                                         context:nil];
    NSDecimalNumber *zscoreStdDev = [plateStdDevExpression expressionValueWithObject:nil
                                                                             context:nil];

    //iterate through samples in each plate and perform calculation, update CoreData
    for (ScreenVariables *zValue in eachPlateArray) {
        NSDecimalNumber *deltaTemp = [zValue valueForKey:@"delta"];
        NSDecimalNumber *numerator = [deltaTemp decimalNumberBySubtracting:zscoreMean];
        NSDecimalNumber *zScoreValue = [numerator decimalNumberByDividingBy:zscoreStdDev];
        [zValue setZScore:zScoreValue];

问题在于,当我运行这个计算时,我应该从〜(-6,6)得到一个数字,其中99%的值落在-3和3之间。返回的一个数据点是:

  

257849691392950000000000000000000000000000000000000000000000000000000000000000000

好的,我通过将变量deltaTempnumeratorzscoreMeanzscoreStdDev插入我的NSTableView进行了一些故障排除。我们的想法是看看XCode正在评估这些变量,并找出麻烦制造者。它是否使用此代码:

ScreenVariables *addData = [NSEntityDescription insertNewObjectForEntityForName:@"ScreenVariables"
                                                         inManagedObjectContext:self.managedObjectContext];
[addData setValue:deltaTemp forKey:@"someAvailableKey-1"];
[addData setValue:numerator forKey:@"someAvailableKey-2"];
[addData setValue:zscorePlateMean forKey:@"someAvailableKey-3"];
[addData setValue:zscoreStdDev forKey:@"someAvailableKey-4"];

我得到了变量的值:

deltaTemp = -919
zscoreMean = -141
numerator = -919    // should be -778.58 = -919 -(-141)
zscoreStdDev = 1337.635067946411

评估为Z-Score = -0.581 ...

这是一个完全有效的ZScore ...所以问题在于:

[deltaTemp decimalNumberBySubtracting:zscoreMean];
[numerator decimalNumberByDividingBy:zscoreStdDev];

变量分子未正确评估,zscore值也不正确。我的CoreData DataModel SPECIFICALLY将每个数字变量的输入类型定义为NSDecimalNumber,所以我假设我的数字编码很好,因为它们是单独插入而没有任何问题...

1 个答案:

答案 0 :(得分:1)

NSDecimalNumber *zscoreMean = [plateMeanExpression  expressionValueWithObject:nil context:nil];
NSDecimalNumber *zscoreStdDev = [plateStdDevExpression expressionValueWithObject:nil context:nil];

这些是对NSNumber对象的评估,而不是NSDecimalNumber对象...不确定为什么我没有得到任何错误。

    NSNumber *expMean = [plateMeanExpression  expressionValueWithObject:nil context:nil];
    NSNumber *expStdDev = [plateStdDevExpression expressionValueWithObject:nil context:nil];

    NSDecimalNumber *zscoreMean = [NSDecimalNumber decimalNumberWithDecimal:[expMean decimalValue]];
    NSDecimalNumber *zscoreStdDev = [NSDecimalNumber decimalNumberWithDecimal:[expStdDev decimalValue]];

这很好用。