• Home

CodingExperiments.com

Linux, PHP, and the blogosphere

Search

Category:

  • Apple Inc.
  • Apps
  • Facts
  • Fun
  • Google
  • Ideas
  • Internet
  • Linux
  • Microsoft
  • PHP
  • Programming
  • Rants
  • Security
  • Uncategorized
  • web 2.0

Archives:

  • June 2009
  • May 2009
  • April 2009
  • March 2009
  • February 2009
  • January 2009
  • December 2008
  • November 2008
  • October 2008
  • September 2008
  • August 2008
  • July 2008
  • June 2008
  • May 2008
  • April 2008
  • March 2008
  • February 2008
  • January 2008
  • December 2007

Pages

  • About
    • The Authors
  • Commenting your code
  • How to Write Papers with Groff
  • ModCMS Anti-Spam Component Set
  • ModCMS Technical Specifications
  • Regular Expressions Guessing Game
  • Saving code directly to a web server
  • The (Almost) Perfect PHP 404 Page

Meta:

  • RSS
  • Comments RSS

Awesomeness tracker

CodingExperiments at Blogged View blog authority
Free Page Rank Tool

Integer->String conversion in C/C++

August 27th, 2008 by i80and

I had cause of late to convert an integer into a string in C.  My research indicated that there was no standardized function to do this, and thus the most portable thing to do was to write my own algorithm.  After fiddling with numbers and masks and such things, I came up with the following core algorithm:

#define CONVERT_DIGIT(mask, n, offset)    (( n/mask - ( n/(mask*10))*10) + offset )

This algorithm may not be as efficient as it could be, but I’m fairly happy with it given that normally I dodge anything with even a distant correlation to mathematics as if it were the plague.  mask is a power of your number system base b; most of the time, this is going to be a power of 10.  n is the number you want to convert.  offset is used to offset the resulting integer to an ASCII equivalent; this could actually be hard-coded as 48.

Given that the number of digits in n is L, you need to initialize mask to bL-1.  Then run a loop that for each digit in n runs CONVERT_DIGIT( mask, n, 48) and then divides mask by b for the next iteration.

Caveats

While the algorithm itself should be O(L), the actual output is going to have some worthless zeros at the start for most values of n that may have to be stripped.  In addition, I’m not going to explain how to create a string in C, or how to implement this in other languages.  You’re on your own there.

Also note that while the premise should be solid and I haven’t seen a situation where it fails, I disavow all responsibility for algorithmic failures and weaknesses.

EDIT: Daniel Bruce informed me that the function sprintf() would do the job just as well, only should also work for floating point numbers and is more flexible.  I wish I had known about that before I had spent the time to write this algorithm.


Posted in Programming |

  • DGentry
    I take it the stdio functions (sprintf/snprintf/etc) were not acceptable? Certainly sprintf is a considerably more heavyweight function than the loop you've defined.
  • i80and
    Honestly? I wasn't aware of sprintf/snprintf when I wrote this. Quite the embarrassing oversight on my part. But ah well; you're right, it probably did speed up the loop I used it in a bit (although I'm not sure if the net difference would be significant). Plus I got a lot of fun out of designing this algorithm.
  • Kenneth Finnegan
    Instead of 48, you could also hard code it as '0' (zero in single quotes), which will evaluate to 48 when compiled, but will be portable if compiled in some other character set, which is good in C.

    Would you mind if I added this to my website of C tricks with citation? http://ctips.pbwiki.com/

    As for the leading zeros, I've used a recursive function where it'll keep calling itself with n/10 until n==0, then add each digit to the next char in the array, index of which is returned back down the call stack. But by then, sprintf would probably be just as good, but you get the idea...
  • i80and
    Yeah, setting the offset to '0' is probably a better idea than 48. Thanks for the tip.

    Sure, go ahead and add it. I'm not sure where it would be more useful than sprintf/snprintf, though. Cool site, incidentally.

    Interesting idea for recursion. I'd have have to play with that to fully get it, but I think I get the general idea.
  • mortonfox
    itoa() does the same thing and in multiple bases too, although it is not a part of ANSI C.
  • i80and
    I had heard of itoa(), but I wanted something fully portable; it didn't really matter in the grand scheme of things as the program was for my own personal use, but I smelled a fun programming problem coming a mile away.

    But thanks anyway.
blog comments powered by Disqus