У меня проблема с decimalNumberBySubtracting и decimalNumberByDividingBy - PullRequest
1 голос
/ 01 февраля 2010

Проще говоря, decimalNumberBySubtracting и decimalNumberByDividingBy не работают ... вообще. Никаких ошибок, только испорченные результаты. Мне действительно нужно это исправить, но я не получаю никаких ошибок, и я не могу придумать какой-либо другой способ, как сделать расчет! Я получаю такие номера, как:

257849691392950000000000000000000000000000000000000000000000000000000000000000000

Где они должны быть оценены до:

-0,581

Вот длинная история. Я пытаюсь сделать простой расчет Z-Score для набора данных. A Zscore определяется как (X - Average)/(stdDev). Довольно просто Мои данные испытаний включают в себя 5 пластин с 96 образцами. Этот код идентифицирует каждую отдельную пластину, генерирует среднее значение и стандартное отклонение для каждой пластины, затем для каждого образца в ТА пластине выполняет вышеуказанный расчет.

//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

Итак, хорошо, я решил некоторые проблемы, вставив переменные deltaTemp, numerator, zscoreMean, zscoreStdDev в мой 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 Ответ

1 голос
/ 01 февраля 2010
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]];

Это сработало прекрасно.

...