Amazon.com Widgets Exercise 6.2 - driving me crazy pls help!
Welcome, Guest. Please login or register.
Did you miss your activation email?
December 22, 2014, 09:16:03 AM
Home Help Search chat Login Register 
News: Read this please.The Great Kangaroo Escape Looking for reviews of the 4th ed on Amazon!   Twitter:  @skochan
                     

+ Official Forum for Programming in Objective-C (the iPhone Programming Language) - Stephen Kochan
|-+ Programming in Objective-C, 4th edition
| |-+ Exercises
| | |-+ Chapter 6
| | | |-+ Exercise 6.2 - driving me crazy pls help!
Pages: [1] Go Down
Print
Author Topic: Exercise 6.2 - driving me crazy pls help! (Read 2016 times)
Sebastiaan76
Newbie
*
Posts: 7


Email




on: February 03, 2012, 08:07:28 PM

Hello,
I can't for the life of me get ex 6.2 to work.

the issue seems to be in the -(void) divide method. for some reason when a div by zero error handling occurs, and the value of accumulator is set to 'NAN' - it causes an issue with the final 'if else' statement in the main program.

with the condition I've put in that final if statement ([deskCalc accumulator] == NAN) - it's basically not recognising the NAN condition and is dropping through to the else statement and doing an NSLog of the accumulator ( which it frustratingly prints out as 'nan' ).

I've tried to test the rest of the program by changing it so that if there is a div by zero it's sets the value of accumulator to 999.99 for example, and then also testing for that condition, which works fine ( it NSLog's the "end" text instead of returning the accumulator ). So I know that the issue is with testing the NAN condition.

My code is below, and would really appreciate some assistance Smiley



Code: (Objective-C)
// Program to evaluate simple expressions of the form
// number operator number
// Implement a Calculator class

#import <Foundation/Foundation.h>

@interface Calculator: NSObject   // create new object called Calculator - subclass of NSObject

// accumulator methods
-(void) setAccumulator: (double) value;  // setter method for Accumulator - takes double integer input - stores in variable 'value'
-(void) clear; // method for clearing a value - doesn't return anything
-(double) accumulator; // method for returning accumulator - returns a double integer

// all these methods are instance methods

// arithmetic methods
-(void) add: (double) value;
-(void) subtract: (double) value;
-(void) multiply: (double) value;
-(void) divide: (double) value;
@end

@implementation Calculator
{
    double accumulator;
}
-(void) setAccumulator: (double) value
{
    accumulator = value;
}
-(void) clear
{
    accumulator = 0;
}
-(double) accumulator
{
    return accumulator;
}
-(void) add: (double) value
{
    accumulator += value;
}
-(void) subtract: (double) value
{
    accumulator -= value;
}
-(void) multiply: (double) value
{
    accumulator *= value;
}
-(void) divide: (double) value
{
    if ( value !=0.0)
        accumulator /= value;
    else {
        NSLog (@"Division by zero error");
        accumulator = NAN;}
    }
@end


int main (int argc, const char * argv[])
{

    @autoreleasepool {
       
        double value1, value2;
        char operator;
       
       
        Calculator *deskCalc = [[Calculator alloc] init];
        NSLog (@"Type in your expression.");
        scanf ("%lf %c %lf", &value1, &operator, &value2);
        [deskCalc setAccumulator: value1];
        if ( operator == '+' )
            [deskCalc add: value2];
        else if ( operator == '-' )
            [deskCalc subtract: value2];
        else if ( operator == '*' )
            [deskCalc multiply: value2];
        else if ( operator == '/' )
            [deskCalc divide: value2];
         
        if ([deskCalc accumulator] == NAN)
            NSLog(@"end");
        else
        NSLog (@"%.2f", [deskCalc accumulator]);
           

       
    }
   
   
    return 0;
}
Logged
Sebastiaan76
Newbie
*
Posts: 7


Email




Reply #1 on: February 03, 2012, 08:32:00 PM

OK.I've found 2 ways to test for NAN, but given neither of them seem to be explicitly covered in this section of the book, so I'm thinking this isn't what the author intended!
Code: (Objective-C)
if (isnan([deskCalc accumulator]))


or

Code: (Objective-C)
if ([deskCalc accumulator] != [deskCalc accumulator])

I'm not even entirely sure about why the second one works - unless it is testing the object as to whether it's a (int)?

Last Edit: February 03, 2012, 08:40:50 PM by Sebastiaan76 Logged
skochan
Administrator
Hero Member
*****
Posts: 3114







Reply #2 on: February 03, 2012, 08:45:41 PM

THe first approach way is the right way to test for NAN.  In fact, you can't do any sort of comparison of a value against NAN as it's defined to always return FALSE (which explains the second result).

Cheers,

Steve
Logged
Sebastiaan76
Newbie
*
Posts: 7


Email




Reply #3 on: February 03, 2012, 09:06:52 PM

Thanks Steven,
I just learned a heap in the last few hours!

fortunately the other part of the exercise ( not printing the accumulator if an incorrect operator is used ) was much easier to figure out.

I can officially say ex 6.2 is completed successfully Smiley

my final code:

Code: (Objective-C)
// Program to evaluate simple expressions of the form
// number operator number
// Implement a Calculator class

#import <Foundation/Foundation.h>

@interface Calculator: NSObject   // create new object called Calculator - subclass of NSObject

// accumulator methods
-(void) setAccumulator: (double) value;  // setter method for Accumulator - takes double integer input - stores in variable 'value'
-(void) clear; // method for clearing a value - doesn't return anything
-(double) accumulator; // method for returning accumulator - returns a double integer

// all these methods are instance methods

// arithmetic methods
-(void) add: (double) value;
-(void) subtract: (double) value;
-(void) multiply: (double) value;
-(void) divide: (double) value;
@end

@implementation Calculator
{
    double accumulator;
}
-(void) setAccumulator: (double) value
{
    accumulator = value;
}
-(void) clear
{
    accumulator = 0;
}
-(double) accumulator
{
    return accumulator;
}
-(void) add: (double) value
{
    accumulator += value;
}
-(void) subtract: (double) value
{
    accumulator -= value;
}
-(void) multiply: (double) value
{
    accumulator *= value;
}
-(void) divide: (double) value  // built in test of Div by zero
{
    if ( value !=0.0)
        accumulator /= value;
    else {
        NSLog (@"Division by zero error");
        accumulator = NAN;}
    }
@end


int main (int argc, const char * argv[])
{

    @autoreleasepool {
       
        double value1, value2;
        char operator;
       
       
        Calculator *deskCalc = [[Calculator alloc] init];
        NSLog (@"Type in your expression.");
        scanf ("%lf %c %lf", &value1, &operator, &value2);
        [deskCalc setAccumulator: value1];
        if ( operator == '+' )
            [deskCalc add: value2];
        else if ( operator == '-' )
            [deskCalc subtract: value2];
        else if ( operator == '*' )
            [deskCalc multiply: value2];
        else if ( operator == '/' )
            [deskCalc divide: value2];
        else if ( operator !='+' || operator !='-' || operator !='*' || operator !='/' )  // test to see if the operator not equal to +, -, * or /
        {                                                                                 // if it is, print an error message and set accumulator to NAN
            NSLog (@"Invalid Operator used");                                             // this will be caught by the following block of if/else statements 
            [deskCalc setAccumulator: NAN];
        }
         
        if (isnan([deskCalc accumulator])) // check whether the accumulator is currently NaN using the 'insnan()' if true NSLog "end"   
            NSLog(@"end");
        else
            NSLog (@"%.2f", [deskCalc accumulator]) ; // if it's not a NaN NSlog the value of accumulator
    }
return 0;
}
Logged
Trizney
Newbie
*
Posts: 8


Email




Reply #4 on: February 27, 2012, 12:32:56 AM

I went a different way with this. I added a bool for the Unknown Operator, and then an if-else for the displaying of the accumulator. It checks for the bool, and we know what value2 is as it's being entered by the user, if bool != YES and value2 != 0, it will print out the accumulator.

Code: (Objective-C)

int main (int argc, const char * argv[])
{
   
    @autoreleasepool {
       
        bool unknown;
        double value1, value2;
        char operator;
       
        Calculator *deskCalc = [[Calculator alloc] init];
       
        NSLog (@"Type in your expression.");
        scanf ("%lf %c %lf", &value1, &operator, &value2);
       
        [deskCalc setAccumulator: value1];
        if ( operator == '+' )
            [deskCalc add: value2];
        else if ( operator == '-' )
            [deskCalc subtract: value2];
        else if ( operator == '*' )
            [deskCalc multiply: value2];
        else if ( operator == '/' )
            [deskCalc divide: value2];
        else {
            NSLog (@"Unknown operator");
            unknown = YES;
        }
           
        if ( unknown != YES && value2 != 0 )
            NSLog(@"%.2f", [deskCalc accumulator]);
Logged
kritchens
Newbie
*
Posts: 10






Reply #5 on: March 11, 2012, 09:08:29 AM

i just did a return 0; in both cases so it would prevent any more action from the program.

i do understand there are a few different ways that this could be done.

with either adding elseif clauses. or adding checks (if else's) within the division method.

Logged
Chingon
Newbie
*
Posts: 3






Reply #6 on: May 01, 2012, 12:46:08 PM

I went a different way with this. I added a bool for the Unknown Operator, and then an if-else for the displaying of the accumulator. It checks for the bool, and we know what value2 is as it's being entered by the user, if bool != YES and value2 != 0, it will print out the accumulator.


My solution was almost identical, but instead of the bool I just set operator to '?'

Code: (Objective-C)
int main(int argc, const char * argv[])
{
    
    @autoreleasepool {
        double    value1, value2;
        char      operator;
        
        Calculator *deskCalc = [[Calculator alloc] init];
        
        NSLog(@"Type in your expression.");
        scanf("%lf %c %lf", &value1, &operator, &value2);
        
        [deskCalc setAccumulator: value1];
        if ( operator == '+' )
            [deskCalc add: value2];
        else if ( operator == '-' )
            [deskCalc substract: value2];
        else if ( operator == '*' )
            [deskCalc multiply: value2];
        else if ( operator == '/' )
            [deskCalc divide: value2];
        else {
            operator = '?';
            NSLog(@"Unknown operator.");
        }
              
        if (operator != '?' && value2 != 0.0)
            NSLog (@"%.2f", [deskCalc accumulator]);
    }
    return 0;
}
Last Edit: May 01, 2012, 12:47:57 PM by Chingon Logged
mo7ionsickness
Jr. Member
**
Posts: 50






Reply #7 on: July 24, 2012, 10:08:05 AM

here's mine:

Code: (Objective-C)
int main(int argc, const char * argv[])
{

    @autoreleasepool {
       
        double  value1, value2;
        char    operator;
        Calculator *deskCalc = [[Calculator alloc] init];
       
        NSLog(@"Type in your expression.");
        scanf("%lf %c %lf", &value1, &operator, &value2);
       
        [deskCalc setAccumulator:value1];
       
        if (operator == '+'){
            [deskCalc add:value2];
            NSLog(@"%.2f", [deskCalc accumulator]);
        }
        else if (operator == '-'){
            [deskCalc subract:value2];
            NSLog(@"%.2f", [deskCalc accumulator]);
        }
        else if (operator == '*'){
            [deskCalc multiply:value2];
            NSLog(@"%.2f", [deskCalc accumulator]);
        }
        else if (operator == '/')
            if (value2 == 0)
                NSLog(@"Division by zero");
            else {
                [deskCalc divide:value2];
                NSLog(@"%.2f", [deskCalc accumulator]);
            }
        else
            NSLog(@"Unkown operator");
       
    }
    return 0;
}

output 1:


2012-07-24 18:06:20.155 prog6[4791:403] Type in your expression.
10 / 0
2012-07-24 18:06:28.845 prog6[4791:403] Division by zero

output 2:


2012-07-24 18:07:04.098 prog6[4795:403] Type in your expression.
10 ? 2
2012-07-24 18:07:19.510 prog6[4795:403] Unkown operator

Logged
mo7ionsickness
Jr. Member
**
Posts: 50






Reply #8 on: July 24, 2012, 10:24:43 AM

ok I revised my code from above, credit goes to Trizney:

Code: (Objective-C)
int main(int argc, const char * argv[])
{

    @autoreleasepool {
       
        BOOL valid = YES;
        double  value1, value2;
        char    operator;
        Calculator *deskCalc = [[Calculator alloc] init];
       
        NSLog(@"Type in your expression.");
        scanf("%lf %c %lf", &value1, &operator, &value2);
       
        [deskCalc setAccumulator:value1];
       
        if (operator == '+')
            [deskCalc add:value2];
        else if (operator == '-')
            [deskCalc subract:value2];
        else if (operator == '*')
            [deskCalc multiply:value2];
        else if (operator == '/')
            if (value2 == 0) {
                NSLog(@"Division by zero");
                valid = NO;
            }
            else
                [deskCalc divide:value2];
        else {
            NSLog(@"Unkown operator");
            valid = NO;
        }
       
        if (valid)
            NSLog(@"%.2f", [deskCalc accumulator]);
    }
    return 0;
}

output 1:

2012-07-24 18:19:16.760 prog6[4821:403] Type in your expression.
2?2
2012-07-24 18:19:20.085 prog6[4821:403] Unkown operator

output 2:

2012-07-24 18:23:59.579 prog6[4827:403] Type in your expression.
1/0
2012-07-24 18:24:02.417 prog6[4827:403] Division by zero
Logged
RobinS
Newbie
*
Posts: 1






Reply #9 on: August 17, 2012, 06:40:08 AM

I di it this way though I think its overkill

Code: (Objective-C)
      double value1, value2;
       
        char operator;
       
        Calculator *deskCalc = [[Calculator alloc] init];
       
        NSLog(@"Type in your expresssion.");
        scanf("%lf %c %lf", &value1, &operator , &value2);
       
        [deskCalc setAccumulator: value1];
       
        if (operator == '+')
            [deskCalc add: value2];
        else if (operator == '-')
            [deskCalc subtract: value2];
        else if (operator == '*')
            [deskCalc multiply: value2];
        else if (operator == '/')
            [deskCalc divide: value2];
        else
            NSLog(@"%c is an Unknown Operator", operator);
       
               
       
       
        if (isnan([deskCalc accumulator]))
            NSLog(@"End");
        else
            switch (operator){
            case '+':
            case '-':
            case '*':
            case '/':
                    NSLog(@"%.2g", [deskCalc accumulator]);
            break;
            default:
                    NSLog(@"");
            }


Logged
Pages: [1] Go Up
Print
Jump to:



Login with username, password and session length

Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!
Entire forum contents (c) 2009 classroomM.com. All rights reserved.