tag:blogger.com,1999:blog-203063759820106893.post3600876880054893189..comments2023-03-25T08:30:26.602-04:00Comments on A Moment of Zen: Parsing IntegersJeffrey Stedfasthttp://www.blogger.com/profile/12271561115384429651noreply@blogger.comBlogger19125tag:blogger.com,1999:blog-203063759820106893.post-28341058940871991142008-05-19T11:30:00.000-04:002008-05-19T11:30:00.000-04:00excelente código la importancia en peerfomance que...excelente código la importancia en peerfomance que se alcanza vale más que la legibiidad del código que se logro o acaso ustedes lo pueden mejorar tabulando el codigo <BR/>jajaja<BR/>good work<BR/>excellent fineAnonymousnoreply@blogger.comtag:blogger.com,1999:blog-203063759820106893.post-25280347898519452932007-12-02T11:50:00.000-05:002007-12-02T11:50:00.000-05:00You only need stdint.h for the [u]int*_t definitio...You only need stdint.h for the [u]int*_t definitions, which you can typedef yourself easily enough.Jeffrey Stedfasthttps://www.blogger.com/profile/12271561115384429651noreply@blogger.comtag:blogger.com,1999:blog-203063759820106893.post-34106363512617388872007-11-27T15:22:00.000-05:002007-11-27T15:22:00.000-05:00you say that this code is useful because some syst...you say that this code is useful because some systems may lack strtol, well, haha, your code relies on stdint.h which is less likely to be available than strtol ;DAnonymousnoreply@blogger.comtag:blogger.com,1999:blog-203063759820106893.post-18701917107476195652007-11-15T13:46:00.000-05:002007-11-15T13:46:00.000-05:00Let me try to explain better what I had meant by "...Let me try to explain better what I had meant by "swap the sign":<BR/><BR/>if (sign < 0)<BR/> val = (val * sign * 10) - digit;<BR/>...<BR/><BR/>since sign == -1 and the number we are parsing is -39, here's what happens:<BR/><BR/>first pass we get:<BR/> val = (0 * -1 * 10) - 3;<BR/><BR/>as desired, this results in -3. Good so far... However, the next time through your loop we get:<BR/><BR/> val = (-3 * -1 * 10) - 9;<BR/><BR/>which results in 21.<BR/><BR/>This is why it is important not to apply the sign until we are done with the loop.<BR/><BR/>Hope that helps explain the logic in my implementation.Jeffrey Stedfasthttps://www.blogger.com/profile/12271561115384429651noreply@blogger.comtag:blogger.com,1999:blog-203063759820106893.post-31002411211053654642007-11-15T13:39:00.000-05:002007-11-15T13:39:00.000-05:00Anonymous,1. What is "screwed up" in my implementa...Anonymous,<BR/><BR/>1. What is "screwed up" in my implementation?<BR/><BR/>2. Your code doesn't have the proper number of closing braces so I'm not sure I can even follow what you are trying to do... I can only assume you meant to close off the while-loop before the "if (inptr == in)" check.<BR/><BR/>If my assumption is correct, then your code is broken for negative values. Every iteration through the loop will swap the sign. For example, if the number we are parsing is "-39", your function would parse the value as 21 which is clearly wrong.Jeffrey Stedfasthttps://www.blogger.com/profile/12271561115384429651noreply@blogger.comtag:blogger.com,1999:blog-203063759820106893.post-91201699582780826652007-11-14T16:21:00.000-05:002007-11-14T16:21:00.000-05:00I think that signed integer parsing routine is scr...I think that signed integer parsing routine is screwed up. Probably it should go like this (i omitted backslashes at the end of every line):<BR/><BR/>#define STRTOINT(bits, max) <BR/>static int <BR/>strtoint##bits (const char *in, char **inend, <BR/> int##bits##_t *retval, int *err) <BR/>{ <BR/> register const char *inptr = in; <BR/> int##bits##_t val = 0; <BR/> int digit, sign = 1; <BR/> <BR/> while (*inptr == ' ') <BR/> inptr++; <BR/> <BR/> if (*inptr == '-') { <BR/> sign = -1; <BR/> inptr++; <BR/> } <BR/> <BR/> in = inptr; <BR/> while (*inptr >= '0' && *inptr <= '9') {<BR/> digit = (*inptr - '0'); <BR/> if (val > (max / 10)) { <BR/> *err = EOVERFLOW; <BR/> return -1; <BR/> } else if (val == (max / 10)) { <BR/> if (digit > (max % 10) && <BR/> (sign > 0 || digit > ((max % 10) + 1))) { <BR/> *err = EOVERFLOW; <BR/> return -1; <BR/> } <BR/> <BR/> if (sign < 0) <BR/> val = (val * sign * 10) - digit; <BR/> else <BR/> val = (val * 10) + digit; <BR/> <BR/> inptr++;<BR/> }<BR/> <BR/> if (inptr == in) { <BR/> *err = EINVAL; <BR/> return -1; <BR/> } <BR/><BR/> *inend = (char *) inptr; <BR/> *retval = val; <BR/> <BR/> return 0; <BR/>}Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-203063759820106893.post-38123734696029907762007-11-13T16:42:00.000-05:002007-11-13T16:42:00.000-05:00Okay, I've just replaced the tab size to be 4 spac...Okay, I've just replaced the tab size to be 4 spaces rather than 8, hope that helps alleviate the viewing problems people are having.Jeffrey Stedfasthttps://www.blogger.com/profile/12271561115384429651noreply@blogger.comtag:blogger.com,1999:blog-203063759820106893.post-23328631840164767742007-11-13T14:31:00.000-05:002007-11-13T14:31:00.000-05:00Jeffrey - the code's tab size is set too large (8 ...Jeffrey - the code's tab size is set too large (8 spaces). Could you replace the tabs with 3 or 4 spaces? Cheers!Turlyhttps://www.blogger.com/profile/01313311916172146471noreply@blogger.comtag:blogger.com,1999:blog-203063759820106893.post-11597020333719248962007-11-13T14:25:00.000-05:002007-11-13T14:25:00.000-05:00The code is unreadable. The right hand sides of t...The code is unreadable. The right hand sides of the code blocks are hidden behind the sidebar. The lines are cut off well before the backslashes a previous commentator complained about.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-203063759820106893.post-33154410873711823752007-11-13T10:45:00.000-05:002007-11-13T10:45:00.000-05:00Anonymous,The code is a C-macro template, the idea...Anonymous,<BR/><BR/>The code is a C-macro template, the idea is that you could expand it to implement a parser routine for any size integer (8, 16, 32, 64, 128, etc) without the need to rewrite any new code, just allowing the preprocessor to do it for you.<BR/><BR/>Benjamin,<BR/><BR/>Yes, strtol() and friends do indeed handle many more bases than just 10, but typically you want to parse base10 integers (or at least that's what I usually find myself parsing ;-)<BR/><BR/>It should be fairly trivial to change the code to parse base8 or base16, etc (which are probably the 2 most common other than 10).<BR/><BR/>As far as eating white space before the numeric value, my code already eats 0x20, but you could fix that up easily to use isspace() :)<BR/><BR/>As far as MIN_INT, if I'm understanding what you are asking, my code does handle MIN_INT properly. See the following logic:<BR/><BR/>if (digit > (max % 10) && (sign > 0 || digit > ((max % 10) + 1))) {<BR/><BR/>You'll see there that my code recognizes that MIN_INT is (-MAX_INT - 1).Jeffrey Stedfasthttps://www.blogger.com/profile/12271561115384429651noreply@blogger.comtag:blogger.com,1999:blog-203063759820106893.post-50385386035874873912007-11-13T07:40:00.000-05:002007-11-13T07:40:00.000-05:00WOW!@Anonymous: it a macro, thus all the slashes!WOW!<BR/><BR/>@Anonymous: it a macro, thus all the slashes!Joaquim Rendeirohttps://www.blogger.com/profile/16469523562298686196noreply@blogger.comtag:blogger.com,1999:blog-203063759820106893.post-65135297042690370402007-11-13T03:16:00.000-05:002007-11-13T03:16:00.000-05:00I think this is missing support for MININT (- MAXI...I think this is missing support for MININT (- MAXINT - 1).<BR/>Also, strtol() does radians other than 10, in particular hex numbers. And I think it also uses isspace() for skipping spaces at the beginning of the string.Benjaminhttps://www.blogger.com/profile/06585580573568488010noreply@blogger.comtag:blogger.com,1999:blog-203063759820106893.post-57436747366230928742007-11-13T03:03:00.000-05:002007-11-13T03:03:00.000-05:00Yeah, but please work on your snippet layout.The a...Yeah, but please work on your snippet layout.<BR/>The above is almost unreadable. What's with all those backslashes every other line?Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-203063759820106893.post-73282847946564987852007-11-08T18:09:00.000-05:002007-11-08T18:09:00.000-05:00Where did you learn to program?Every one of your c...Where did you learn to program?<BR/><BR/>Every one of your code snippets is incredible. They are all so clean, concise and all so elegant!<BR/><BR/>Please please please! Post more code snippets!Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-203063759820106893.post-9832488275682161552007-11-08T08:25:00.000-05:002007-11-08T08:25:00.000-05:00Ah, good point... I should probably state on my bl...Ah, good point... I should probably state on my blog that all code that I post is licensed under MIT/X11 unless otherwise specified.Jeffrey Stedfasthttps://www.blogger.com/profile/12271561115384429651noreply@blogger.comtag:blogger.com,1999:blog-203063759820106893.post-83250506809362429702007-11-07T22:58:00.000-05:002007-11-07T22:58:00.000-05:00What license might this be under?What license might this be under?Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-203063759820106893.post-70212065683433185152007-11-07T22:21:00.000-05:002007-11-07T22:21:00.000-05:00Nevermind, it should always work.Nevermind, it should always work.Jeffrey Stedfasthttps://www.blogger.com/profile/12271561115384429651noreply@blogger.comtag:blogger.com,1999:blog-203063759820106893.post-22261559650726309112007-11-07T22:17:00.000-05:002007-11-07T22:17:00.000-05:00I suppose you could use:int##bits##_t max = (1 but...I suppose you could use:<BR/><BR/>int##bits##_t max = (1 << (bits - 1)) - 1;<BR/><BR/>but it's likely harder for the c compiler to optimize that than a constant.<BR/><BR/>Plus I'm not sure my bit hack will always work for signed integer types.Jeffrey Stedfasthttps://www.blogger.com/profile/12271561115384429651noreply@blogger.comtag:blogger.com,1999:blog-203063759820106893.post-26860345053314085732007-11-07T19:02:00.000-05:002007-11-07T19:02:00.000-05:00Why do you need to pass the maximum number? Surely...Why do you need to pass the maximum number? Surely some variant on (1 << bits) would do the job?Stuarthttps://www.blogger.com/profile/05164178689698873586noreply@blogger.com