Thread: Is there a standard function?

  1. #151
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I fail to see why you insist on using outdated compilers.
    I also found this:
    Warning 1 warning C4996: 'ultoa': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _ultoa. See online help for details.
    (Yes, it says C++ for some reason even when it's compiling C code with a C compiler.)
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  2. #152
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Quote Originally Posted by Elysia View Post
    I fail to see why you insist on using outdated compilers.
    I also found this:
    Warning 1 warning C4996: 'ultoa': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _ultoa. See online help for details.
    (Yes, it says C++ for some reason even when it's compiling C code with a C compiler.)
    MSVC 6.0 works with either ultoa or _ultoa. I'm running Windows, not a POSIX OS, as you know - or did you fail to see that, too?

    I'm testing sprintf(), right now, in my program, on MSVC 6.0. It works accurately, but it increased the run time from 122 seconds, to 205 seconds. <Yikes!>

    I'll stick with ulta/_ulta.

  3. #153
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Adak View Post
    MSVC 6.0 works with either ultoa or _ultoa. I'm running Windows, not a POSIX OS, as you know - or did you fail to see that, too?
    You are the one who used the POSIX version...
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #154
    Registered User
    Join Date
    Jun 2010
    Posts
    182
    All standard functions are big chunk of code for the simple
    reason they handle generic situations, quite a lot indeed, like
    printf(). This is one of the reasons they are usually slower than
    simpler versions you can manage to code, if you really want to.

    If I'm trying to have a faster function, a faster itoa() or ultoa()
    I have to bother with coding it myself. I need to do some experimentation.

    Pelles'C has indeed a _ultoa() and a _itoa(), named this way
    to indicate that they are not ANSI standard C, but extensions.

    I can find an hundred version of them. But where is the fun?
    What I learn? How do I understand how to code in C if I
    don't bother with some reinventing the wheel here and there?

    If I had to build a massive 10 million lines application I'd
    probably use whatever fits the task.

    Here I'm just learning some C syntax, so it is more fun to
    reinvent the wheel sometime.

    So far no standard function was faster than the crumpled
    example I posted. It is the product of a beginner C learner
    and it is already faster than usual standard printf(), itoa()
    or the like.

    So please don't come again with this story of using what is
    available, I'm not in a hurry, I can bother spending some weeks
    enjoyng coding, trying, learning from your examples and
    aiming at a faster function. :-)

    It is a game, if you enjoy it, just play with it for a while. ;-)
    Last edited by frktons; 07-06-2010 at 10:58 AM.

  5. #155
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Yeah, but presumably they both print the result faster that you can read.

  6. #156
    Registered User
    Join Date
    Jun 2010
    Posts
    182
    Quote Originally Posted by Subsonics View Post
    Yeah, but presumably they both print the result faster that you can read.
    Presumably yes :-)

  7. #157
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,834
    Code:
    void insert_commas(char *inp, char *outp) {
    int a = (21 - (int)strlen(inp)) % 3, d;
    for (; outp[ d = a / 3] = *inp++; a += 4)
    	outp[d + 1] = ',';
    outp[d - 1] = '\0'; }
    
    ...
    
    char buffer[100], buffer2[100];
    int number = -1234567153;
    
    sprintf(buffer, "%d", number);
    insert_commas(buffer, buffer2);
    printf("\"%s\"", buffer2);
    Outputs "-1,234,567,153"
    Last edited by nonoob; 07-06-2010 at 02:29 PM.

  8. #158
    Registered User
    Join Date
    Jun 2010
    Posts
    182
    Quote Originally Posted by nonoob View Post
    Code:
    void insert_commas(char *inp, char *outp) {
    int a = (21 - (int)strlen(inp)) % 3, d;
    for (; outp[ d = a / 3] = *inp++; a += 4)
    	outp[d + 1] = ',';
    outp[d - 1] = '\0'; }
    
    ...
    
    char buffer[100], buffer2[100];
    int number = -1234567153;
    
    sprintf(buffer, "%d", number);
    insert_commas(buffer, buffer2);
    printf("\"%s\"", buffer2);
    Outputs "-1,234,567,153"
    Good and standard solution.
    It is a bit slow due to the use of standard functions
    like sprintf().

    I elaborated 10 million cycles in 5,262 clock ticks:
    Code:
    -1,234,567,153
    
     Elapsed time = 5,262
    Press any key to continue...
    after inserting the missing code:

    Code:
    //-----------------------------------
    // comma_sep.c
    //-----------------------------------
    // version proposed by nonoob
    //-----------------------------------
    
    
    #include <stdio.h>
    #include <string.h>
    #include <time.h>
    
    void insert_commas(char *inp, char *outp) {
       int a = (21 - (int)strlen(inp)) % 3, d;
       for (; outp[ d = a / 3] = *inp++; a += 4)
    	outp[d + 1] = ',';
       outp[d - 1] = '\0';
     }
    
    int main(void){
    
       int times = 10000000; // iterations to test
       int x = 0;
       char buffer[100], buffer2[100];
       int number = -1234567153; // number to format
    
       clock_t start = 0;              // initial time
       clock_t stop = 0;              // end time 
       start = clock();
    
       for (x = 0; x < times; x++){
          sprintf(buffer, "%d", number);
          insert_commas(buffer, buffer2);
       }
       stop = clock();
       int elapsed = (int)(stop-start);
       printf("%s\n", buffer2);
       sprintf(buffer,"%d",elapsed);
       insert_commas(buffer, buffer2);
       printf("\n Elapsed time = %s\n",buffer2);
       return 0;
    }
    Last edited by frktons; 07-06-2010 at 04:58 PM.

  9. #159
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Quote Originally Posted by Elysia View Post
    You are the one who used the POSIX version...
    I'm not on a POSIX system. That is the MSVC (Windows) and Turbo C (DOS) version.
    respectively.

    You are the one who keeps posting these assertions, which you know are incorrect and/or irrelevant.

  10. #160
    Registered User
    Join Date
    Jun 2010
    Posts
    182
    Quote Originally Posted by Adak View Post
    I'm not on a POSIX system. That is the MSVC (Windows) and Turbo C (DOS) version.
    respectively.

    You are the one who keeps posting these assertions, which you know are incorrect and/or irrelevant.
    Hi Adak, try to not be upset by these futile questions.
    There are far more interesting things to do with our intelligence
    and time. :-)

  11. #161
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Sorry to pollute your thread.

    Anyway, I can't get Nonoob's version to work, prints out "15" using the test number of 1234567890. Also, the design of the program is such that it could not print out more than one number, which seems like an advantage over the other programs which could, and stop it via an if statement inside the for loop.

    What's the fastest version so far, on your system?

  12. #162
    Registered User
    Join Date
    Jun 2010
    Posts
    182
    Quote Originally Posted by Adak View Post
    Sorry to pollute your thread.

    Anyway, I can't get Nonoob's version to work, prints out "15" using the
    test number of 1234567890. Also, the design of the program is such that it
    could not print out more than one number, which seems like an advantage
    over the other programs which could, and stop it via an if statement inside the for loop.

    What's the fastest version so far, on your system?
    The fastest version so far is:
    Code:
    // ----------------------------------------------------------------------------------------------
    // Prog_name: comma_sep.c / ver 0.6
    // A routine for formatting integer numbers with thousand separators. 
    // Created with Pelles C for Windows 6.00.4
    //-----------------------------------------------------------------------------------------------
    // This version takes into account the sign and the possibility to have different
    // separator like space, comma, point, and so on. 
    // Moveover this version creates a function that can be tested for performance. 
    // Added the choice for right and left alignment.
    //-----------------------------------------------------------------------------------------------
    // Date: 06 july 2010
    // Author: frktons/clive @ cprogramming forum.
    //-----------------------------------------------------------------------------------------------
    
    #include <stdio.h>
    #include <stdbool.h>
    #include <time.h>
    // #undef getchar
    // #pragma comment(lib, "\\masm32\\lib\\msvcrt.lib")
    
    //-----------------------------------------------------------------------------------------------
    // Global variables. In future versions will go into an header file
    //-----------------------------------------------------------------------------------------------
        bool sign = true;              // if the number has to be displayed with sign
    
        bool zero = false;             // if the number is zero the function sets this
                                                  // flag for its decisions
        char sep = '.';                   // here I choose the separator 
        char buffer[15] = {'\0'};        // string array for the formatted number
                                                  // 10 digits max + 3 separators max + sign + NULL
        char alignment = 'L';       // choice to [R]ight-align or [L]eft-align the number  
    
    //-----------------------------------------------------------------------------------------------
    // Function prototype for int_format(). Takes in the number to format.
    // Returns nothing.
    //-----------------------------------------------------------------------------------------------
    
    void int_format(int num);
    
    //-----------------------------------------------------------------------------------------------
    // Function prototype for testpad(). Displays some info on the screen
    // about the test we are going to perform. Returns nothing.
    //-----------------------------------------------------------------------------------------------
    
    void testpad(void);
    
    //-----------------------------------------------------------------------------------------------
    
    int main(void)
    {
     
        int num = -1234567890;          // test number
        int cycles = 0;
    
    
        int x;                                  // generic integer counter
        clock_t start = 0;              // initial time
        clock_t stop = 0;              // end time 
        float ver = 0.6;                   // Program version
        unsigned long un = num;
     
        int times = 10000000;      // for testing performance set this number for repetitions
    
        printf("\n\t\t\t Testing version : %.2f \n",ver);
        printf("\n\t\t\t ----------------------\n");
        printf("\n The value of num is: %d\n",num);
        printf("\n num after unsigned conversion is %d", un);
    
    
    
        start = clock();
    
        for (cycles = 0; cycles < times; cycles++) {
            for (x=0; x < 15; x++)
                buffer[x] = '\0'; 
            int_format(num);
        } // end for
        
        printf("\n The formatted value of num is: %s",buffer);
        
    
        stop = clock();
    
        sign = false;
        int_format((int)(stop-start));
        printf("\n Elapsed ClickTime: %s",buffer);
        for (x=0; x < 15; x++)
            buffer[x] = ' \0'; 
    
        sign = false;
        int_format(times);
        printf("\n to perform %s",buffer);
        printf(" cycles of the formatting function");
        getchar();
        return 0;
    }
    //--------------------------------------------------------------------
    // Function int_format()
    //--------------------------------------------------------------------
    void int_format(int num)
    {
      register int x = 0;
      register int y = 0;
      int remain = 0;                               // integer variable to store the remainder
      register int count = 0;                    // integer counter for positioning the separator
      const int len_str = sizeof(buffer) - 1;                 // string length less the terminator NULL
      const int ten = 10;
      bool neg = false;              // if the number is negative this flag will be set
                                                // from the function to reflect the state
    
      x = len_str;
    
      if (num != 0)
      {
        zero = false;
    
        if (num < 0)
        {
          neg = true;
          num = -num;                            // transform number to positive if negative
        }
        else
          neg = false;
    
        while(num)
        {
          if (count == 3)
        {
          count = 0;
          buffer[x--] = sep;
          }
    
          buffer[x--] = '0' + (char)(num % ten);
    
          num = num / ten;
    
          count++;
        }
    
        if (sign == true)
        {
          if (neg == true)
            buffer[x] = '-';
          else
            buffer[x] = '+';
        }
        else
           x++;
      }
      else
      {
        buffer[x] = '0';
    
        zero = true;
      }
    
      if (alignment  == 'L')
      {
        if (x == 0)
         return;
    
        for (y = 0; y < sizeof(buffer); y++, x++)
        {
          buffer[y] = buffer[x];
    
          if (buffer[y] == '\0')
            return;
         } // end for
      }
    
      return;
    }
    with these results:

    Code:
                             Testing version : 0.60
    
                             --------------------------
    
     The value of num is: -1234567890
    
     The formatted value of num is: -1.234.567.890LL
     Elapsed ClickTime: 1.409L
     to perform 10.000.000L cycles of the formatting function
    But something strange has happened to the string display,
    as you can see an "L" or even 2 appear posrfixed.

    Have you any idea why this happens?
    Last edited by frktons; 07-06-2010 at 06:03 PM.

  13. #163
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Looks like your index has run over, and included the 'L' from the alignment variable, into the number.

    Did you change something in it?

  14. #164
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    Code:
    stop = clock();
    
        sign = false;
        int_format((int)(stop-start));
        printf("\n Elapsed ClickTime: %s",buffer);
        for (x=0; x < 15; x++)
            buffer[x] = ' \0';
    Perhaps that is giving you some trouble?
    Last edited by kermit; 07-06-2010 at 07:03 PM.

  15. #165
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Really, globals?!

    Code:
          if (neg == true)
    You know that's a bit redundant right?
    Just use
    Code:
          if (neg)
    Or better yet, rather than it simply being a boolean flag, change it to a char and simply set it to '-' or '+' isntead of true or false, and avoid an if-test later.

    I guarantee that you can speed up that code furthur by fully unrolling the loop.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  2. Change this program so it uses function??
    By stormfront in forum C Programming
    Replies: 8
    Last Post: 11-01-2005, 08:55 AM
  3. const at the end of a sub routine?
    By Kleid-0 in forum C++ Programming
    Replies: 14
    Last Post: 10-23-2005, 06:44 PM
  4. c++ linking problem for x11
    By kron in forum Linux Programming
    Replies: 1
    Last Post: 11-19-2004, 10:18 AM
  5. Replies: 5
    Last Post: 02-08-2003, 07:42 PM