1 votes

J'ai un problème avec decimalNumberBySubtracting et decimalNumberByDividingBy.

C'est simple, decimalNumberBySubtracting y decimalNumberByDividingBy ne fonctionnent pas ... du tout. Il n'y a pas d'erreur, juste des résultats erronés. J'ai vraiment besoin de résoudre ce problème, mais je ne reçois aucune erreur et je ne vois pas d'autre moyen de faire le calcul ! J'obtiens des chiffres comme :

257849691392950000000000000000000000000000000000000000000000000000000000000000000

Où ils devraient être évalués :

-0.581

Voici la longue histoire. J'essaie d'effectuer un simple calcul de Z-Score sur un ensemble de données. A Zscore est défini comme suit (X - Average)/(stdDev) . C'est assez simple. Mes données d'essai comprennent 5 plaques contenant chacune 96 échantillons. Ce code identifie chaque plaque individuelle, génère la moyenne et la stdev pour chaque plaque, puis pour chaque échantillon dans CETTE plaque, effectue le calcul ci-dessus.

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

Le problème est que lorsque j'exécute ce calcul, je devrais obtenir un nombre compris entre ~(-6,6) et 99 % des valeurs comprises entre -3 et 3. Voici un des points de données renvoyés :

257849691392950000000000000000000000000000000000000000000000000000000000000000000

Bon, d'accord, j'ai fait un peu de dépannage en insérant les variables deltaTemp , numerator , zscoreMean , zscoreStdDev dans mon NSTableView. L'idée était de voir à quoi XCode évaluait ces variables et de corriger celle qui posait problème. Je l'ai fait en utilisant ce code :

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"];

J'ai des valeurs pour mes variables :

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

Cela donne un score Z de -0.581...

C'est un ZScore parfaitement valide ... donc le problème est dans la :

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

Le numérateur de la variable n'est pas évalué correctement et la valeur du zscore non plus. Dans mon modèle de données CoreData, le type d'entrée de chaque variable numérique est SPECIFIQUEMENT défini comme NSDecimalNumber. Je suppose donc que l'encodage des nombres est correct, car ils sont insérés individuellement sans problème...

1voto

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

Ces derniers évaluaient les objets NSNumber, et non les objets NSDecimalNumber... je ne sais pas pourquoi je n'ai pas eu d'erreur.

    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]];

Cela a fonctionné à merveille.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X