Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #14521 > unrolled thread
| Started by | mrc2323@cox.net (Mike Copeland) |
|---|---|
| First post | 2012-02-26 15:05 -0700 |
| Last post | 2012-02-28 11:43 -0800 |
| Articles | 13 — 10 participants |
Back to article view | Back to comp.lang.c++
Testing for Numeric Digits mrc2323@cox.net (Mike Copeland) - 2012-02-26 15:05 -0700
Re: Testing for Numeric Digits Ian Collins <ian-news@hotmail.com> - 2012-02-27 11:11 +1300
Re: Testing for Numeric Digits Ian Collins <ian-news@hotmail.com> - 2012-02-27 11:22 +1300
Re: Testing for Numeric Digits Paul <pchristor@yahoo.co.uk> - 2012-02-26 16:45 -0800
Re: Testing for Numeric Digits "MikeWhy" <boat042-nospam@yahoo.com> - 2012-02-28 03:17 -0600
Re: Testing for Numeric Digits Paul <pchristor@yahoo.co.uk> - 2012-02-28 03:30 -0800
Re: Testing for Numeric Digits Marc <marc.glisse@gmail.com> - 2012-02-28 15:19 +0000
Re: Testing for Numeric Digits "MikeWhy" <boat042-nospam@yahoo.com> - 2012-02-28 11:04 -0600
Re: Testing for Numeric Digits Andy Champ <no.way@nospam.invalid> - 2012-02-28 20:44 +0000
Re: Testing for Numeric Digits Miles Bader <miles@gnu.org> - 2012-02-27 10:23 +0900
Re: Testing for Numeric Digits scott@slp53.sl.home (Scott Lurndal) - 2012-02-27 17:22 +0000
Re: Testing for Numeric Digits Dombo <dombo@disposable.invalid> - 2012-02-27 20:29 +0100
Re: Testing for Numeric Digits Quint Rankid <qbr567@gmail.com> - 2012-02-28 11:43 -0800
| From | mrc2323@cox.net (Mike Copeland) |
|---|---|
| Date | 2012-02-26 15:05 -0700 |
| Subject | Testing for Numeric Digits |
| Message-ID | <MPG.29b45a9820e6ae9a9896f9@news.eternal-september.org> |
Is there a relatively easy and simple way to determine if a
basic::string value is comprised only of numeric digits? I have an
application that parses a comma-delimited string, and I want to test if
specific values are strictly numeric. It was working until I got a
mixed alphanumeric value that started with a numeric digit (e.g.
"6btt123"), which caused the following code to fail:
int ii = atoi(wStr.c_str());
if(ii) // numeric processing
{
// expecting purely numeric value in "ii"
[etc.]
}
else // alphanumeric processing
{
// process alphanumeric data
}
when it fell into the numeric processing branch.
I know that I could examine the contents of the "wStr" string
character-by-character to test if each character is a digit character,
but that seems slow and inefficient. Is there a better way to do such
processing? Thoughts? TIA
[toc] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2012-02-27 11:11 +1300 |
| Message-ID | <9qvp10F3nfU3@mid.individual.net> |
| In reply to | #14521 |
On 02/27/12 11:05 AM, Mike Copeland wrote:
> Is there a relatively easy and simple way to determine if a
> basic::string value is comprised only of numeric digits? I have an
> application that parses a comma-delimited string, and I want to test if
> specific values are strictly numeric. It was working until I got a
> mixed alphanumeric value that started with a numeric digit (e.g.
> "6btt123"), which caused the following code to fail:
>
> int ii = atoi(wStr.c_str());
Never use atoi(), it has now way to indicate failure. Use strtol() and
check errno.
> if(ii) // numeric processing
> {
> // expecting purely numeric value in "ii"
> [etc.]
> }
> else // alphanumeric processing
> {
> // process alphanumeric data
> }
> when it fell into the numeric processing branch.
> I know that I could examine the contents of the "wStr" string
> character-by-character to test if each character is a digit character,
> but that seems slow and inefficient. Is there a better way to do such
> processing? Thoughts? TIA
What are you reading form? iterating a sting is orders of magnitude
faster than reading from a file.
--
Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2012-02-27 11:22 +1300 |
| Message-ID | <9qvpl3F3nfU4@mid.individual.net> |
| In reply to | #14522 |
On 02/27/12 11:11 AM, Ian Collins wrote: > > Never use atoi(), it has now way to indicate failure. Use strtol() and > check errno. Usual Monday morning keyboard issues: "no way to indicate failure.". -- Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | Paul <pchristor@yahoo.co.uk> |
|---|---|
| Date | 2012-02-26 16:45 -0800 |
| Message-ID | <35f84f6f-cb9f-494f-9e0e-9153a4484759@gw9g2000vbb.googlegroups.com> |
| In reply to | #14523 |
On Feb 26, 10:22 pm, Ian Collins <ian-n...@hotmail.com> wrote: > On 02/27/12 11:11 AM, Ian Collins wrote: > > > > > Never use atoi(), it has now way to indicate failure. Use strtol() and > > check errno. > > Usual Monday morning keyboard issues: "no way to indicate failure.". > > -- > Ian Collins Whatabout isdigit?
[toc] | [prev] | [next] | [standalone]
| From | "MikeWhy" <boat042-nospam@yahoo.com> |
|---|---|
| Date | 2012-02-28 03:17 -0600 |
| Message-ID | <jii62j$s3k$1@dont-email.me> |
| In reply to | #14525 |
Paul wrote:
> On Feb 26, 10:22 pm, Ian Collins <ian-n...@hotmail.com> wrote:
>> On 02/27/12 11:11 AM, Ian Collins wrote:
>>
>>
>>
>>> Never use atoi(), it has now way to indicate failure. Use strtol()
>>> and check errno.
>>
>> Usual Monday morning keyboard issues: "no way to indicate failure.".
>>
>> --
>> Ian Collins
>
> Whatabout isdigit?
isdigit uses locale stuff, I think, and is not as trivial as you might like.
(I might have that confused with atoi.)
bool is_ascii_digit(char c)
{ return (c ^ 0x30) <= 9;
}
Xor flips the bits corresponding to 1's in the mask. ASCII digits are in the
range 0x30 to 0x39. In other words, the high nybble has to contain 0x3.
After xor'ing with 0x30 (or '0'), the high nybble can be zero only if the
high nybble was 0x3. Any other value has a non-zero high nybble, and the <=
test fails. The comparison also requires the low nybble is less than 0xa.
[toc] | [prev] | [next] | [standalone]
| From | Paul <pchristor@yahoo.co.uk> |
|---|---|
| Date | 2012-02-28 03:30 -0800 |
| Message-ID | <7d83ea06-0972-4212-87e8-7ea245f05934@em9g2000vbb.googlegroups.com> |
| In reply to | #14579 |
On Feb 28, 9:17 am, "MikeWhy" <boat042-nos...@yahoo.com> wrote:
> Paul wrote:
> > On Feb 26, 10:22 pm, Ian Collins <ian-n...@hotmail.com> wrote:
> >> On 02/27/12 11:11 AM, Ian Collins wrote:
>
> >>> Never use atoi(), it has now way to indicate failure. Use strtol()
> >>> and check errno.
>
> >> Usual Monday morning keyboard issues: "no way to indicate failure.".
>
> >> --
> >> Ian Collins
>
> > Whatabout isdigit?
>
> isdigit uses locale stuff, I think, and is not as trivial as you might like.
> (I might have that confused with atoi.)
I think there are two versions of isdigit() one simple version is part
of std string, the other is a template for use with locale. The locale
version is very easy to use but it may be a little slower than the
simpler version.
>
> bool is_ascii_digit(char c)
> { return (c ^ 0x30) <= 9;
>
> }
>
> Xor flips the bits corresponding to 1's in the mask. ASCII digits are in the
> range 0x30 to 0x39. In other words, the high nybble has to contain 0x3.
> After xor'ing with 0x30 (or '0'), the high nybble can be zero only if the
> high nybble was 0x3. Any other value has a non-zero high nybble, and the <=
> test fails. The comparison also requires the low nybble is less than 0xa.
IIRC there is a more portable way to do this without using fixed hex
values to mask so that it will work on any system, not just ASCII. I
can't remember the exact algorithm right now though.
The lib functions will probably be similar, and just as efficient.
[toc] | [prev] | [next] | [standalone]
| From | Marc <marc.glisse@gmail.com> |
|---|---|
| Date | 2012-02-28 15:19 +0000 |
| Message-ID | <jiira9$ceh$1@news-rocq.inria.fr> |
| In reply to | #14579 |
"MikeWhy" wrote:
> bool is_ascii_digit(char c)
> { return (c ^ 0x30) <= 9;
> }
>
> Xor flips the bits corresponding to 1's in the mask. ASCII digits are in the
> range 0x30 to 0x39. In other words, the high nybble has to contain 0x3.
> After xor'ing with 0x30 (or '0'), the high nybble can be zero only if the
> high nybble was 0x3. Any other value has a non-zero high nybble, and the <=
> test fails. The comparison also requires the low nybble is less than 0xa.
(unsigned)c-'0'<10 seems easier to remember...
[toc] | [prev] | [next] | [standalone]
| From | "MikeWhy" <boat042-nospam@yahoo.com> |
|---|---|
| Date | 2012-02-28 11:04 -0600 |
| Message-ID | <jij1e9$p9v$1@dont-email.me> |
| In reply to | #14585 |
"Marc" <marc.glisse@gmail.com> wrote in message
news:jiira9$ceh$1@news-rocq.inria.fr...
> "MikeWhy" wrote:
>
>> bool is_ascii_digit(char c)
>> { return (c ^ 0x30) <= 9;
>> }
>>
>> Xor flips the bits corresponding to 1's in the mask. ASCII digits are in
>> the
>> range 0x30 to 0x39. In other words, the high nybble has to contain 0x3.
>> After xor'ing with 0x30 (or '0'), the high nybble can be zero only if the
>> high nybble was 0x3. Any other value has a non-zero high nybble, and the
>> <=
>> test fails. The comparison also requires the low nybble is less than 0xa.
>
> (unsigned)c-'0'<10 seems easier to remember...
xor has a smaller carbon footprint. Subtraction has additional transistors
in the borrow circuits, which consume power when flipping state. (Hell is
exothermic, I believe, was the conclusion given in one such discussion.)
[toc] | [prev] | [next] | [standalone]
| From | Andy Champ <no.way@nospam.invalid> |
|---|---|
| Date | 2012-02-28 20:44 +0000 |
| Message-ID | <8NCdnf-t47FeodDSnZ2dnUVZ7rKdnZ2d@eclipse.net.uk> |
| In reply to | #14579 |
On 28/02/2012 09:17, MikeWhy wrote: > > isdigit uses locale stuff, I think, and is not as trivial as you might like. Right. Are these digits? 42 (Japanese full width - different to 42) Or this? Ⅲ (Roman numeral three). Or these? ④② (digits in circles on my font) I've tried to set this to UTF-8 so you have some hope of reading it, but... This is of course OT. Andy
[toc] | [prev] | [next] | [standalone]
| From | Miles Bader <miles@gnu.org> |
|---|---|
| Date | 2012-02-27 10:23 +0900 |
| Message-ID | <87aa45ax37.fsf@catnip.gol.com> |
| In reply to | #14521 |
mrc2323@cox.net (Mike Copeland) writes:
> I know that I could examine the contents of the "wStr" string
> character-by-character to test if each character is a digit character,
> but that seems slow and inefficient. Is there a better way to do such
> processing? Thoughts? TIA
if (wStr.find_first_not_of ("0123456789") == string::npos)
=> All chars are digits
[Most efficient? I dunno. But reasonably concise...]
-miles
--
Alone, adj. In bad company.
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2012-02-27 17:22 +0000 |
| Message-ID | <NZO2r.76005$o65.73941@news.usenetserver.com> |
| In reply to | #14521 |
mrc2323@cox.net (Mike Copeland) writes:
> Is there a relatively easy and simple way to determine if a
>basic::string value is comprised only of numeric digits? I have an
>application that parses a comma-delimited string, and I want to test if
>specific values are strictly numeric. It was working until I got a
>mixed alphanumeric value that started with a numeric digit (e.g.
>"6btt123"), which caused the following code to fail:
>
> int ii = atoi(wStr.c_str());
Use strtol or strtoul.
char *cp;
ulong_t line = strtoul(argv[2], &cp, 0);
if ((cp == argv[2]) // String (argv[2]) didn't start with digit or is empty
|| (*cp != '\0') // String had non-digit before end of string
|| (line >= MAX_DCDLP_LINES)) { // Converted value is illegel
lp->log("%s Illegal line number '%s' specified\n",
t_dlp_name, argv[2]);
return true;
}
s
[toc] | [prev] | [next] | [standalone]
| From | Dombo <dombo@disposable.invalid> |
|---|---|
| Date | 2012-02-27 20:29 +0100 |
| Message-ID | <4f4bd980$0$14712$5fc3050@news.tiscali.nl> |
| In reply to | #14521 |
Op 26-Feb-12 23:05, Mike Copeland schreef:
> Is there a relatively easy and simple way to determine if a
> basic::string value is comprised only of numeric digits? I have an
> application that parses a comma-delimited string, and I want to test if
> specific values are strictly numeric. It was working until I got a
> mixed alphanumeric value that started with a numeric digit (e.g.
> "6btt123"), which caused the following code to fail:
>
> int ii = atoi(wStr.c_str());
> if(ii) // numeric processing
> {
> // expecting purely numeric value in "ii"
> [etc.]
> }
> else // alphanumeric processing
> {
> // process alphanumeric data
> }
> when it fell into the numeric processing branch.
> I know that I could examine the contents of the "wStr" string
> character-by-character to test if each character is a digit character,
> but that seems slow and inefficient.
Why do you think that iterating over the string and testing with
isdigit() would be slower than using atoi()? After all atoi() would have
to examine each character in the string as well, and would have to do
some computation on top of that.
[toc] | [prev] | [next] | [standalone]
| From | Quint Rankid <qbr567@gmail.com> |
|---|---|
| Date | 2012-02-28 11:43 -0800 |
| Message-ID | <8f97c78a-c6dc-4d37-af20-48d53691e61b@db5g2000vbb.googlegroups.com> |
| In reply to | #14521 |
On Feb 26, 5:05 pm, mrc2...@cox.net (Mike Copeland) wrote: > Is there a relatively easy and simple way to determine if a > basic::string value is comprised only of numeric digits? Maybe std::string::find_first_not_of. > I know that I could examine the contents of the "wStr" string > character-by-character to test if each character is a digit character, > but that seems slow and inefficient. Is there a better way to do such > processing? Thoughts? TIA I think you will have to examine each character. There may be ways to speed this up depending on how much knowledge you have about the data. IE, are there likely patterns that will occur with non-digits? Or are those cases what someone might informally describe as being random. Quint.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c++
csiph-web