Performing arithmetic on double

rattletrap99

I have an app whose purpose is to compare chronologically ordered time intervals, which are stored by Core Data (via MagicalRecord) as attributes of type double, on an entity called TimedActivity. Ordering directions are supplied by attributes called activityOfInterest and benchmarkActivity on another entity named SearchSpecs. The scheme may seem a bit overcomplicated since I'm pretty green, but that part of it works.

The problem is that getting percentages from two doubles appears to be a bit of a runaround, at least according to the research I've done. I don't need extreme precision. Round seconds are fine. I found a suggestion relating to the use of NSDecimalNumber, but it too seemed like a long way around the corner.

Here is the relevant code in it's current state, with pseudocode to indicate my problem area:

#pragma mark - Go button case handlers

-(void) handleAvsAAction
{
//    NSArray *searchSpecsObjects = [SearchSpecs MR_findAll];
//    NSLog(@"SearchSpecs number of objects is %i",[searchSpecsObjects count]);

    NSArray *searchSpecsArray = [SearchSpecs MR_findAll];
    NSLog(@"searchSpecsArray count is %i", [searchSpecsArray count]);

    SearchSpecs *thisSpec = [searchSpecsArray objectAtIndex:0];
    NSLog(@"SearchSpec activityOfInterest should be %@", thisSpec.activityOfInterest);
    NSLog(@"SearchSpec benchmarkActivity should be %@", thisSpec.benchmarkActivity);

    //    NSArray *activityOfInterestArray;
//    NSArray *benchmarkActivityArray;
    NSNumber *activityOfInterestDurationTotal;
    NSNumber *benchmarkActivityDurationTotal;

    NSPredicate *activityOfInterestPredicate = [NSPredicate predicateWithFormat:@"name == '%@'",thisSpec.activityOfInterest];

    NSPredicate *benchmarkActivityPredicate = [NSPredicate predicateWithFormat:@"name == '%@'", thisSpec.benchmarkActivity];

    activityOfInterestDurationTotal = [TimedActivity MR_aggregateOperation:@"sum:" onAttribute:@"duration" withPredicate:activityOfInterestPredicate];
    NSLog(@"The sum of all the durations for the activity of interest is %zd", activityOfInterestDurationTotal);

    benchmarkActivityDurationTotal = [TimedActivity MR_aggregateOperation:@"sum:" onAttribute:@"duration" withPredicate:benchmarkActivityPredicate];
    NSLog(@"The sum of all the durations for the benchmark activity is %zd", benchmarkActivityDurationTotal);

    [self doTheMathAvsA];

}

-(void) doTheMathAvsA
{
    // Get the total and respective percentages of the totalled durations from the criteria distilled in handleAvsAAction

NSNumber *total;
total = (activityOfInterestDurationTotal + benchmarkActivityDurationTotal);

}

Edit: modified doTheMathAvsA to clarify the desired result.

All help or suggestions appreciated!

Second edit:

OK, your answer below makes sense, and thanks @Martin R!

However, the two quantities in question here originate as NSTimeIntervals, and as mentioned above, are stored as attributes of type double, on an entity called TimedActivity.

So, it seemed rational to me to slightly rewrite the code to extract them from the persistent store as NSTimeIntervals, which I am assured are really just doubles. However, when I do this, I get this error:

Assigning to 'NSTimeInterval' (aka 'double') from incompatible type 'NSNumber *'

Here are the modified declarations:

NSTimeInterval activityOfInterestDurationTotal;
NSTimeInterval benchmarkActivityDurationTotal;

And here's where the error appears:

activityOfInterestDurationTotal = [TimedActivity MR_aggregateOperation:@"sum:" onAttribute:@"duration" withPredicate:activityOfInterestPredicate];
NSLog(@"The sum of all the durations for the activity of interest is %@", activityOfInterestDurationTotal);

benchmarkActivityDurationTotal = [TimedActivity MR_aggregateOperation:@"sum:" onAttribute:@"duration" withPredicate:benchmarkActivityPredicate];
NSLog(@"The sum of all the durations for the benchmark activity is %@", benchmarkActivityDurationTotal);

OK, I assume that the NSNumber referred to in the error message is this property in the TimedActivity managed object subclass, auto-generated from the data model:

@property (nonatomic, retain) NSNumber * duration;

So my question becomes:

Is it really necessary to resort to such seemingly ever-widening circles of conversion and retro-conversion to perform such a seemingly simple calculation? Or am I missing a more straightforward solution?

Thanks!

Martin R

You cannot perform arithmetic directly on NSNumber objects. The easiest solution is to convert them to double for the addition:

double tmp = [activityOfInterestDurationTotal doubleValue] + [benchmarkActivityDurationTotal doubleValue];

and the result back to NSNumber, if necessary:

NSNumber *total = @(tmp);

Update: By default, the Xcode generated accessor methods use Objective-C objects even for primitive Core Data types such as "Double". You can change that by selecting the "Use scalar properties for primitive data types" option when creating the subclass files. Then a "Double" property is declared as

@property (nonatomic) double activityOfInterestDurationTotal;

and you can access it "directly" as for example

NSTimeInterval duration = thisActivity.duration;

because NSTimeInterval is just another name for double.

But there is another problem: The MagicalRecord "convenience method" MR_aggregateOperation: uses a special fetch request with NSDictionaryResultType to fetch the sum of all duration values. And even if you chose to use a scalar property for the duration, the result of MR_aggregateOperation: is always some Objective-C object, in this case NSNumber, there is no way around it.

So the only way to avoid a conversion between NSNumber and double would be to use a scalar property as described above, and instead of using MR_aggregateOperation:, fetch all objects and add the duration values yourself in a simple loop.

But note that the fetch request with the aggregate operation performs the calculations on the SQLite level, this is probably more effective then actually fetching all objects.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

How to overwrite NaN or Infinity result when performing arithmetic on Double?

From Dev

Performing arithmetic operation in YAML?

From Dev

Performing arithmetic in SQL query

From Dev

Performing arithmetic on list indexes

From Dev

Difficulty performing arithmetic with dates in R

From Dev

Performing double induction in Welder

From Dev

Performing double AJAX call

From Dev

Performing arithmetic with chars in C/C++

From Dev

Performing arithmetic on a void pointer in C++

From Dev

Event Listener to Performing Arithmetic Operations on TextFields

From Dev

Splitting an array by performing an arithmetic function in ruby

From Dev

Performing Javascript floating point arithmetic in Python

From Dev

C: imprecision in arithmetic of double

From Dev

bash and arithmetic comparison: double quotes or not?

From Dev

float128 and double-double arithmetic

From Dev

float128 and double-double arithmetic

From Dev

Why do I lose the remainder of a value after performing arithmetic in C?

From Dev

Are there utility methods for performing unsafe arithmetic in VB.NET?

From Dev

Performing arithmetic operations on hex-like string in Perl

From Dev

Performing a simple arithmetic operation using SSE (IA32 assembly)

From Dev

Performing a simple arithmetic operation using SSE (IA32 assembly)

From Dev

Performing arithmetic with assignment of named vector in data.table

From Dev

Changing the order of the array contents by performing arithmetic operations in PHP

From Dev

Performing a double integral over a matrix of limits

From Dev

Why C# arithmetic on double appears to be faster than arithmetic on long?

From Dev

.NET and beyond: best practices for using double arithmetic

From Dev

Script fails to parse arithmetic comparison with double bracket

From Dev

Having trouble performing double XSLT transform (daisy chain))

From Dev

Performing arithmetic with a multi-index pandas dataframe that needs broadcasting at several levels

Related Related

  1. 1

    How to overwrite NaN or Infinity result when performing arithmetic on Double?

  2. 2

    Performing arithmetic operation in YAML?

  3. 3

    Performing arithmetic in SQL query

  4. 4

    Performing arithmetic on list indexes

  5. 5

    Difficulty performing arithmetic with dates in R

  6. 6

    Performing double induction in Welder

  7. 7

    Performing double AJAX call

  8. 8

    Performing arithmetic with chars in C/C++

  9. 9

    Performing arithmetic on a void pointer in C++

  10. 10

    Event Listener to Performing Arithmetic Operations on TextFields

  11. 11

    Splitting an array by performing an arithmetic function in ruby

  12. 12

    Performing Javascript floating point arithmetic in Python

  13. 13

    C: imprecision in arithmetic of double

  14. 14

    bash and arithmetic comparison: double quotes or not?

  15. 15

    float128 and double-double arithmetic

  16. 16

    float128 and double-double arithmetic

  17. 17

    Why do I lose the remainder of a value after performing arithmetic in C?

  18. 18

    Are there utility methods for performing unsafe arithmetic in VB.NET?

  19. 19

    Performing arithmetic operations on hex-like string in Perl

  20. 20

    Performing a simple arithmetic operation using SSE (IA32 assembly)

  21. 21

    Performing a simple arithmetic operation using SSE (IA32 assembly)

  22. 22

    Performing arithmetic with assignment of named vector in data.table

  23. 23

    Changing the order of the array contents by performing arithmetic operations in PHP

  24. 24

    Performing a double integral over a matrix of limits

  25. 25

    Why C# arithmetic on double appears to be faster than arithmetic on long?

  26. 26

    .NET and beyond: best practices for using double arithmetic

  27. 27

    Script fails to parse arithmetic comparison with double bracket

  28. 28

    Having trouble performing double XSLT transform (daisy chain))

  29. 29

    Performing arithmetic with a multi-index pandas dataframe that needs broadcasting at several levels

HotTag

Archive