1

I'm working on this very simple and basic script on page 66 of "Sams Teach Yourself C Programming."

Basically, the script asks you for some number of seconds.
You enter a number, then it calculates how many Hours Minutes and Seconds they constitute.

Then I modified the script a little to explore the code and make it just a bit less dull.
The modifications include expanding the range of acceptable input and output.

In the code provided below, I have used comments to indicate the original code, the modifications, and additions.

And finally, at the very end I have added comments to illustrate several very wacky outputs.

**** indicates an incremental examination of the count **** ****indicates a dramatic change in the output in response to very small change in the input (i.e. 1 digit).

I first noticed the problem when I randomly input 85000000.

I've made every effort to streamline the code to make it easier to focus on the math.
I'm not sure if it's a math problem or a typo.

Anyway, here's the code:

/* Illustrates the modulus operator. */
/* inputs a number of seconds, and converts to hours, minutes, and seconds. */
// minute = 60 seconds                  : 60
// hour = 60 * 60 seconds               : 3600
// day = 24 * 60 * 60 seconds           : 86400
// year = 365 * 24 * 60 * 60 seconds    : 31536000

#include <stdio.h>                                      // from original script

/* Define constants */

#define SECS_PER_MIN 60                                 // from original script
#define MIN_PER_HOUR 60
#define HOURS_PER_DAY 24
#define DAYS_PER_YEAR 365
#define SECS_PER_YEAR 31536000
#define SECS_PER_HOUR 3600                              // from original script
#define SECS_PER_DAY 86400
#define LIMIT 2147438647

unsigned int seconds, minutes, hours, days, years, secs_remain, mins_remain, hours_remain, days_remain;     // modified from original script

int main(void)                                                                                          // from original script
{
    seconds = minutes = hours = days = years = secs_remain = mins_remain = hours_remain = days_remain = 0;
    /* Input the number of seconds. */

    printf( "Enter the number of seconds ( > 0, < %u ): \n", LIMIT );                  // modified from original script
    scanf( "%d", &seconds );                                                                            // from original script

    years = seconds /SECS_PER_YEAR;
    days = seconds / SECS_PER_DAY;
    hours = seconds / SECS_PER_HOUR;                                                                    // from original script
    minutes = seconds / SECS_PER_MIN;                                                                   // from original script
    days_remain = days / DAYS_PER_YEAR;      // ***missing 22643200 seconds, given input: 85000000***
    hours_remain = hours % HOURS_PER_DAY;
    mins_remain = minutes % MIN_PER_HOUR;                                                               // modified from original script
    secs_remain = seconds % SECS_PER_MIN;                                                               // from original script

    printf( "%u seconds is equal to ", seconds );                                                       // from original script

    if ( seconds < SECS_PER_HOUR )
    {
         printf( "%u m, and %u s\n", minutes, secs_remain );
         return 0;
    }
         else if((seconds >= SECS_PER_HOUR ) && (seconds < SECS_PER_DAY ))
         {
              printf( "%u h, %u m, and %u s\n", hours, mins_remain, secs_remain );                  // from original script
              return 0;                                                                             // from original script
         }    
         else if((seconds >= SECS_PER_DAY ) && (seconds < SECS_PER_YEAR ))
         {
              printf( "%u d, %u h, %u m, and %u s\n", days, hours_remain, mins_remain, secs_remain );
              return 0;
         }            
         else if((seconds >= SECS_PER_YEAR ) && (seconds < LIMIT ))
         {
             printf( "%u y %u d, %u h, %u m, and %u s\n", years, days_remain, hours_remain, mins_remain, secs_remain );  // calculation day's inaccurate
             return 0;
         }   
         else if(seconds > LIMIT )
         {
             printf("error: excessive amount of seconds.\n");
             printf("range for seconds must be between 0 and %u!\n", LIMIT );
             printf("If number of seconds exceeds %u, then it is beyond range for type 'int'.\n", LIMIT );
             printf("EXITING seconds program. \n");
             return 1;
         }
    }

// ERROR: 31536000 seconds is equal to 1 y 1 d, 0 h, 0 m, and 0 s
// ERROR: 63072000 seconds is equal to 2 y 2 d, 0 h, 0 m, and 0 s
// ERROR: 70000000 seconds is equal to 2 y 2 d, 4 h, 26 m, and 40 s                         ****
// ERROR: 78840000 seconds is equal to 2 y 2 d, 12 h, 0 m, and 0 s                          ****
// ERROR: 90000000 seconds is equal to 2 y 2 d, 16 h, 0 m, and 0 s                          ****
// ERROR: 92500000 seconds is equal to 2 y 2 d, 14 h, 26 m, and 40 s                        ****
// ERROR: 93750000 seconds is equal to 2 y 2 d, 1 h, 40 m, and 0 s                          ****
// ERROR: 94380000 seconds is equal to 2 y 2 d, 8 h, 40 m, and 0 s                          ****
// ERROR: 94537500 seconds is equal to 2 y 2 d, 4 h, 25 m, and 0 s                          ****
// ERROR: 94576875 seconds is equal to 2 y 2 d, 15 h, 21 m, and 15 s                        ****
// ERROR: 94596562 seconds is equal to 2 y 2 d, 20 h, 49 m, and 22 s                        ****
// ERROR: 94606406 seconds is equal to 2 y 2 d, 23 h, 33 m, and 26 s                        ****
// ERROR: 94607636 seconds is equal to 2 y 2 d, 23 h, 53 m, and 56 s                        ****
// ERROR: 94607943 seconds is equal to 2 y 2 d, 23 h, 59 m, and 3 s                         ****
// ERROR: 94607981 seconds is equal to 2 y 2 d, 23 h, 59 m, and 41 s                        ****
// ERROR: 94607990 seconds is equal to 2 y 2 d, 23 h, 59 m, and 50 s                        ****
// ERROR: 94607995 seconds is equal to 2 y 2 d, 23 h, 59 m, and 55 s                        ****
// ERROR: 94607998 seconds is equal to 2 y 2 d, 23 h, 59 m, and 58 s                        ****
// ERROR: 94607999 seconds is equal to 2 y 2 d, 23 h, 59 m, and 59 s                        ****    ****
// ERROR: 94608000 seconds is equal to 3 y 3 d, 0 h, 0 m, and 0 s                           ****    ****
// ERROR: 94608174 seconds is equal to 3 y 3 d, 0 h, 2 m, and 54 s                          ****
// ERROR: 94608097 seconds is equal to 3 y 3 d, 0 h, 1 m, and 37 s                          ****
// ERROR: 94608251 seconds is equal to 3 y 3 d, 0 h, 4 m, and 11 s                          ****
// ERROR: 94608867 seconds is equal to 3 y 3 d, 0 h, 14 m, and 27 s                         ****
// ERROR: 94611328 seconds is equal to 3 y 3 d, 0 h, 55 m, and 28 s                         ****
// ERROR: 94616250 seconds is equal to 3 y 3 d, 2 h, 17 m, and 30 s                         ****
// ERROR: 94695000 seconds is equal to 3 y 3 d, 0 h, 10 m, and 0 s                          ****
// ERROR: 95000000 seconds is equal to 3 y 3 d, 12 h, 53 m, and 20 s                        ****
// ERROR: 100000000 seconds is equal to 3 y 3 d, 9 h, 46 m, and 40 s                        ****
// ERROR: 122990400 seconds is equal to 3 y 3 d, 12 h, 0 m, and 0 s
// ERROR: 126144000 seconds is equal to 4 y 4 d, 0 h, 0 m, and 0 s
Suraj Jain
  • 4,463
  • 28
  • 39
Vasqi
  • 125
  • 9

2 Answers2

2

In Your Code Line,

days_remain = days / DAYS_PER_YEAR;    // ***missing 22643200 seconds, given input: 85000000***

Here It Should Be % Instead Of /, You Have Mistakenly Written It Incorrect.

Also When I Saw This Part Of Your Code, I Had Doubt Maybe This Won't Work

else if(seconds > LIMIT )
             {
                 printf("error: excessive amount of seconds.\n");
                 printf("range for seconds must be between 0 and %u!\n", LIMIT );
                 printf("If number of seconds exceeds %u, then it is beyond range for type 'int'.\n", LIMIT );
                 printf("EXITING seconds program. \n");
                 return 1;
              }

Please See This Validate max integer in scanf To See How to Validate Input Given By User.

Suraj Jain
  • 4,463
  • 28
  • 39
  • you are correct, that last part doesn't work (as expected). I put that there to see what would happen if I entered a value that exceeded the range for type int, but if nothing went wrong, then I wanted to provide a means for it to demonstrate that the excessive value was accepted (despite being out of range). – Vasqi Feb 11 '17 at 12:16
  • The actual result was that the excessive value was in fact accepted, assigned, and displayed. – Vasqi Feb 11 '17 at 12:19
  • It cannot be what is excessive value , what did you entered ? and also you are taking input with %d and printing with %u why ? – Suraj Jain Feb 11 '17 at 12:22
  • the test value that I used was: "2147438650". I also thought that the switch from %d to %u was strange, but I'm just a student, and I was simply following from a script on page 66 of "Sams Teach Yourself C Programming" 7th edition. – Vasqi Feb 11 '17 at 12:27
  • print it with %d , tell me what does it tell ? – Suraj Jain Feb 11 '17 at 12:29
  • Enter the number of seconds ( > 0, < 2147438647 ): 2147438650 2147438650 seconds is equal to error: excessive amount of seconds. range for seconds must be between 0 and 2147438647! If number of seconds exceeds 2147438647, then it is beyond range for type 'int'. EXITING seconds program. – Vasqi Feb 11 '17 at 12:33
  • here's an interesting output: Enter the number of seconds ( > 0, < 2147438647 ): 9876543210 1286608618 seconds is equal to 40 y 291 d, 7 h, 16 m, and 58 s – Vasqi Feb 11 '17 at 12:42
  • can you ask this question? – Suraj Jain Feb 11 '17 at 12:45
  • http://stackoverflow.com/questions/42176318/unsigned-long-int-accepts-out-of-range-values – Vasqi Feb 11 '17 at 13:19
  • you did wrong in question , yours is %d , write there signed int – Suraj Jain Feb 11 '17 at 13:23
  • I just changed all "%d" to "%u" and recompiled... Enter the number of seconds ( > 0, < 2147483647 ): 2147483650 2147483650 seconds is equal to error: 2147483650 is an excessive amount of seconds. range for seconds must be between 0 and 2147483647! If number of seconds exceeds 2147483647, then it is beyond range for type 'int'. EXITING seconds program. [bad_cat@KittyLitter LearningCode]$ – Vasqi Feb 11 '17 at 13:41
1

Edit your code like this: days_remain = days % DAYS_PER_YEAR;