Amazon.com Widgets Exercise 6.6
Welcome, Guest. Please login or register.
Did you miss your activation email?
July 31, 2014, 06:40:50 PM
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
|-+ Old Stuff
| |-+ Answers to Exercises
| | |-+ Chapter 6
| | | |-+ Exercise 6.6
Pages: 1 2 [3] 4 5 6 Go Down
Print
Author Topic: Exercise 6.6 (Read 19616 times)
Sammy
Newbie
*
Posts: 7






Reply #30 on: May 09, 2009, 02:21:22 PM

And one more:
Code: (Objective-C)
#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
double userValue, memoryValue;

NSLog(@"Enter number:");
scanf("%lf", &userValue);

if (userValue < 0 ) {
NSLog (@"Negative");
userValue = -userValue;
}

memoryValue = userValue;

while (userValue >= 10){
userValue /= 10;
}
while (userValue <= memoryValue){
switch ((int) userValue % 10){
case 0:
NSLog(@"zero");
break;
case 1:
                      // ... and so on through case 9
}
if (userValue == 0)
break;
userValue *= 10;
}

    [pool drain];
    return 0;
}
Logged
lmiller5
Newbie
*
Posts: 3






Reply #31 on: May 10, 2009, 11:19:06 AM

Well, I'm probably going to get beaten for jumping ahead, but what can I say? I'm a rebel Wink
Like someone else, I also used a 'C' style array. I'm not sure why that's a problem, since Objective C is a superset of 'C'.

Here is my code and it all works. He was right, though - this was kinda hard.

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   
   int        inNum;   
   int        inNumLen;
   char      pos;
   long int  andx;

   
   NSString   *numStr  = [NSString new];   
   NSNumberFormatter *formatter= [NSNumberFormatter new];
   const char *prntNum[] = {"Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine"};   
   
   printf("\nPlease enter a positive Number: ");
   scanf("%di", &inNum);

   if (inNum < 0)
    {   
       printf("\nERROR - Negitive numbers are not allowed");
    }
   else
     {   
         numStr   = [formatter stringFromNumber: [NSNumber numberWithInt: inNum]];
         inNumLen = [numStr length];
         
         
         NSLog(@"\n\nThe number you entered was: %@", numStr);
         printf("\nYour number in English is:\n");
         
         for (int idx = 0; idx < inNumLen; idx++)
          {
             pos  = [numStr characterAtIndex: idx];
             andx = pos - '0';
             printf("\n%s", prntNum[andx]);      
          }
       printf("\n\n");
     }
   
    [pool drain];
    return 0;
}

I'll take any comments. Thanks...

- Larry
Logged
skochan
Administrator
Hero Member
*****
Posts: 3114







Reply #32 on: May 11, 2009, 05:31:44 AM

@Sammy:  Do you meed the break statement since you already have a terminating condition in your while loop. Also, since you're doing this with floating point numbers, I'm wondering if there might be some cases where you end up with problems due to the inherent inaccuracies when storing floating values (e.g. the number 5.0 getting internally represented as 4.99999999999999).


@Larry:  Yes, this is a combination of too many things that haven't been taught by this point in the text.

Cheers,

Steve Kochan
Logged
Sammy
Newbie
*
Posts: 7






Reply #33 on: May 11, 2009, 11:46:36 AM

Quote
Do you need the break statement since you already have a terminating condition in your while loop.

Before I added that break, I was returning an endless loop when I entered '0' as my user value (because 0 *= 10 still satisfies my terminating condition).

Quote
Also, since you're doing this with floating point numbers, I'm wondering if there might be some cases where you end up with problems due to the inherent inaccuracies when storing floating values (e.g. the number 5.0 getting internally represented as 4.99999999999999).
When I initially wrote the program, I used "float" instead of "double", and I saw some of the errors you're talking about (i.e. 856 came back as "eight" "five" "five"). Changing the values from float to double seemed to eliminate the errors I ran into while testing/debugging; still, this is probably not the preferred method if you need absolute 100% accuracy, especially since I would imagine that errors would be chip/OS specific. It was just the solution that seemed to make the most sense in my head given what I knew.
Logged
slessardjr
Newbie
*
Posts: 15

tranquility1011
Email




Reply #34 on: May 17, 2009, 03:54:05 PM

My Attempt:

Code: (Objective-C)
#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

int right_digit, numberCount;
long long int number, reverseNumber; // Declared for Large Numbers
char repeatProgram = 'n';

do
{
//Initialize Variables and also resets values
right_digit = 0;
numberCount = 1;
reverseNumber = 0;
number = 0;

printf("Enter your number : ");
scanf(" %lli", &number);
printf("\n");

//If Number is Negative Display Negative and Take the Absolute Value
if (number < 0)
{
printf("negative\n");
number = -number;
}

//Construct the Inverse Of the number ex 123 should be 321 and store it into reverse number
do
{
right_digit = number % 10;
reverseNumber *= 10;
reverseNumber += right_digit;
number /= 10;
numberCount++;
}while (number!= 0);

//Take Number and Display Digits As Words
for(; numberCount >1 ; numberCount--)
{
right_digit = reverseNumber % 10;

switch (right_digit)
{
case 1:
printf("one\n");
break;
case 2:
printf("two\n");
break;
case 3:
printf("three\n");
break;
case 4:
printf("four\n");
break;
case 5:
printf("five\n");
break;
case 6:
printf("six\n");
break;
case 7:
printf("seven\n");
break;
case 8:
printf("eight\n");
break;
case 9:
printf("nine\n");
break;
default:
printf("zero\n");
break;
}

reverseNumber /= 10;
}

//Repeat Program Query Loop Begin
printf("\n\nWould You Like Repeat The Program? (y or n)  : ");
scanf(" %c", &repeatProgram);

while(repeatProgram!= 'y' && repeatProgram != 'n'){
printf("INVALID ENTRY!!!!\n");
printf("RETRY : Would You Like Restart? (y or n)  : ");
scanf(" %c", &repeatProgram);
}
printf("\n");

//Reset Number Count
numberCount = 1;

//Repeat Program Query Loop End
}while (repeatProgram == 'y');

    printf("\n\n END PROGRAM \n\n");
   
    [pool drain];
    return 0;
}

Just using the methods given to me from reading the book in order I'm pretty happy with this method; as I'm sure from reading this forum there are more efficient ways of handling this problem and also using less memory.
Logged

~Steve
skochan
Administrator
Hero Member
*****
Posts: 3114







Reply #35 on: May 17, 2009, 04:00:56 PM

Well done!  Good use of comments and well-formatted.

Cheers,

Steve Kochan
Logged
fu_ming_xia
Newbie
*
Posts: 4


Email




Reply #36 on: May 17, 2009, 11:29:02 PM

solution with multiple zeros in the end ' 9320000' , please let me know if there is a better way of doing this
Code: (Objective-C)
int num = 0;
BOOL isTrailingZero = YES;
int zeroCounter = 0;
int reversedNumber = 0;

NSLog(@"Please Enter a Number");
scanf("%i",&num);

do{
if(num % 10 > 0 && isTrailingZero){
isTrailingZero = NO; 
}

if(isTrailingZero){
zeroCounter++;
}

reversedNumber += num % 10;
if(num /= 10)
reversedNumber *= 10;
}while(num > 0);

do{
int tempNum = reversedNumber % 10;
switch (tempNum) {
case 1:
NSLog(@"one");
break;
case 2:
NSLog(@"two");
break;
case 3:
NSLog(@"three");
break;
case 4:
NSLog(@"four");
break;
case 5:
NSLog(@"five");
break;
case 6:
NSLog(@"six");
break;
case 7:
NSLog(@"seven");
break;
case 8:
NSLog(@"eight");
break;
case 9:
NSLog(@"nine");
break;
case 0:
NSLog(@"zero");
break;
default:
NSLog(@"Error: Unknown value");
reversedNumber = 0;
break;
}
reversedNumber /= 10;
}while(reversedNumber > 0);

for(int i = 0; i < zeroCounter; i++){
NSLog(@"zero");
}

Logged
slessardjr
Newbie
*
Posts: 15

tranquility1011
Email




Reply #37 on: May 17, 2009, 11:42:27 PM

your method seems to work fine, see my above example to see how I handled my solution.

The short version of that would be I just counted the number of digits and would store the reversed number like we had done in a previous example. so the number 93000 would store 39 with a numbercount of 5.  Then my loop just %10 and uses a switch statement like yours but I have the default: to display the "zero" and its a for loop that that repeats until numbercount is then depleted.

hope you can understand that.  haha
Logged

~Steve
yeti
Newbie
*
Posts: 1






Reply #38 on: May 24, 2009, 04:55:53 AM

Here's my attempt. I tried to avoid looking here first for pointers to see if I could work it out on my own.....only problem with that was it took me all day to work it out!

Oh well, got there in the end Grin

Code: (Objective-C)
// Program to convert a series of numerical characters to it's text equivalent.

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    int number = 0;
int temp = 0;
int numberOfDigits = 0;
int divisor = 1;
int leftDigit = 0;
int remainder = 0;

// Read in our number.
NSLog(@"Please enter an integer:");
scanf("%i", &number);
NSLog(@"Number entered is: %i", number);
NSLog(@"\n");

// Find out how many digits our number contains so we can set the magnitude of our divisor.
temp = number;
while (temp != 0) {
temp /= 10;
divisor *= 10;
++numberOfDigits;
}
divisor /= 10;

// Check if number is negative.
if (number < 0) {
number = -number;
NSLog(@"negative");
}

// If a single zero is entered print result and exit gracefully.
if (number == 0) {
NSLog(@"zero");
return 0;
}

// Extract single digits and print results.
while (divisor != 0) {
leftDigit = number / divisor;
remainder = number % divisor;
number = remainder;
divisor /= 10;
switch (leftDigit) {
case 0:
NSLog(@"zero");
break;
case 1:
NSLog(@"one");
break;
case 2:
NSLog(@"two");
break;
case 3:
NSLog(@"three");
break;
case 4:
NSLog(@"four");
break;
case 5:
NSLog(@"five");
break;
case 6:
NSLog(@"six");
break;
case 7:
NSLog(@"seven");
break;
case 8:
NSLog(@"eight");
break;
case 9:
NSLog(@"nine");
break;
default:
break;
}
}

    [pool drain];
    return 0;
}


Last Edit: May 24, 2009, 05:19:31 AM by yeti Logged
scutter7282
Newbie
*
Posts: 18






Reply #39 on: June 02, 2009, 08:16:07 AM

After reading all of these and comparing my program, if anyone is bored (since I've spent too much time on this one already), does anyone know how to account for entry of non-number characters?  if you enter a letter in mine, I think it converts the character to a number...  and a solution only using concepts through Chapter 6?  Maybe that is a silly request...
Logged
skochan
Administrator
Hero Member
*****
Posts: 3114







Reply #40 on: June 02, 2009, 08:35:09 AM

Yeah, don't worry about this with respect to scanf, as it's a fussy routine and only used to get input into your program without having to develop a UI.   Incidentally, scanf won't convert a non-number to a character, but that will stop its scan.  If it hasn't seen any digits up to that point, it will return zero, meaning it didn't match a number on the input.  (In general, scanf returns the number of items successfully matched and stored in your variables.)

Cheers,

Steve Kochan
Logged
stonerl
Newbie
*
Posts: 1






Reply #41 on: June 08, 2009, 12:42:02 PM

I am using the 1st edition of the book since i use linux, and so far it seems to me that Obj-C 2.0 is only available for the mac Embarrassed. So here is my approach:

Code: (Objective-C)
#import <stdio.h>
#import <objc/Object.h>

int main (int argc, char *argv[])
{
    float number; //to eliminate leading zeros like 01234
    int work_number, counter, work_counter, rest;
    
    printf ("Enter your number.\n");
    scanf ("%f", &number);
    
    for (;number < 0; number = -number)
        printf ("minus ");
    
    work_number = number;

    // counting the digits of the number entered by the user
    if (number != 0){
        for (counter = 0;  work_number > 0; ++counter)
            work_number /= 10;
            
        for (counter; counter != 0; --counter){
            work_number = number;
            for (work_counter = 1 ;work_counter != counter; ++work_counter )
                work_number /= 10;
                rest = work_number % 10;
            switch (rest){
                case 1:
                    printf ("one ");
                    break;
                case 2:
                    printf ("two ");
                    break;
                case 3:
                    printf ("three ");
                    break;
                case 4:
                    printf ("four ");
                    break;
                case 5:
                    printf ("five ");
                    break;
                case 6:
                    printf ("six ");
                    break;
                case 7:
                    printf ("seven ");
                    break;
                case 8:
                    printf ("eight ");
                    break;
                case 9:
                    printf ("nine ");
                    break;
                default:
                    printf ("zero ");
                    break;
            }
        }
    }
    else
        printf ("zero");
    printf ("\n");
    return 0;
}
Last Edit: June 08, 2009, 09:31:42 PM by stonerl Logged
nhohmann
Global Moderator
Jr. Member
*****
Posts: 57







Reply #42 on: June 22, 2009, 05:29:10 AM

My approach was similar to the one provided by reefdiver on page 2 of this thread. 

I first determine the number of decimal places, and then use that information to set an initial factor to divide by (10, 100, 1000, etc.).  This splits the number from left to right.

I also set the variables to long long int so that it will work with numbers greater than 10 digits.

Code:
Code: (Objective-C)
// Chapter 6, exercise 6 (p. 131)

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
long long int number, newNumber, count = -1, factor = 1;

    NSLog (@"Enter a number:");
scanf ("%lli", &number);

// check for negative number

if (number < 0)
{
number = -number;
NSLog (@"negative");
}

switch (number)
{
// check for entry of zero

case 0:
NSLog (@"zero");
break;
default:
{
newNumber = number;

// Determine number of decimal places of entered number

while (number != 0)
{
number /= 10;
++count;
}

// Determine factor to divide by (10, 100, 1000, etc.)

for (; count != 0; --count)
factor *= 10;

// Determine digit from left to right

for (; newNumber > 0; factor /= 10)
{
switch (newNumber / factor)
{
case 1:
NSLog (@"one");
break;
case 2:
NSLog (@"two");
break;
case 3:
NSLog (@"three");
break;
case 4:
NSLog (@"four");
break;
case 5:
NSLog (@"five");
break;
case 6:
NSLog (@"six");
break;
case 7:
NSLog (@"seven");
break;
case 8:
NSLog (@"eight");
break;
case 9:
NSLog (@"nine");
break;
case 0:
NSLog (@"zero");
break;
}
newNumber %= factor;
}

[pool drain];
return 0;
}}
}
Logged
jclermont
Jr. Member
**
Posts: 55


Email




Reply #43 on: June 22, 2009, 10:55:32 AM

I just worked through this exercise and I wanted to share my solution. Let me know what you think and if you see room for improvement. This was a fun exercise!

Code: (Objective-C)
#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

int number, number_length, digit;

NSLog(@"Enter a whole number:");
scanf("%i", &number);

if (number == 0) {
NSLog(@"zero");
} else if (number <= 0) {
number = -number;
}

number_length = floor(log10(number));

while (number_length >= 0) {
digit = floor(number / (pow(10, number_length)));
number -= (digit * pow(10, number_length));
--number_length;

switch (digit) {
case 0:
NSLog(@"zero");
break;
case 1:
NSLog(@"one");
break;
case 2:
NSLog(@"two");
break;
case 3:
NSLog(@"three");
break;
case 4:
NSLog(@"four");
break;
case 5:
NSLog(@"five");
break;
case 6:
NSLog(@"six");
break;
case 7:
NSLog(@"seven");
break;
case 8:
NSLog(@"eight");
break;
case 9:
NSLog(@"nine");
break;
}
}


    [pool drain];
    return 0;
}

Logged
nhohmann
Global Moderator
Jr. Member
*****
Posts: 57







Reply #44 on: June 22, 2009, 12:39:10 PM

Let me know what you think and if you see room for improvement.

Wow.  I imagine you have previous C++ programming experience, because I'm not familiar with "floor" or "pow" -- but it looks like it takes care of business in fewer steps than it took me. 

Looks great.
Logged
Pages: 1 2 [3] 4 5 6 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.