1

How to test if a number stored as string an exponential number (in Linux)?

I can use methods like scanning the numbers and finding if there exists an 'e', but i need a smarter way to find out.

Does there exist any API to quickly find out and tell if it is an exponential number?

I can use brute force approach like searching through the entire string, and getting a single 'e' followed by a +/- and then a number. But i need a quicker and smarter way, which consumes less machine cycles.

P.S: Exponential numbers are numbers like: 43e4, 23e-2 (any number with an e in between)

RajSanpui
  • 11,556
  • 32
  • 79
  • 146
  • 3
    ... what's an exponential number? – flight Sep 21 '11 at 06:36
  • i think they mean 'scientific notation'... – Mitch Wheat Sep 21 '11 at 06:38
  • Did you mean perfect power? Does the number fit on a machine word? – Mysticial Sep 21 '11 at 06:38
  • Are you asking for a simple way to detect in advance whether `printf` will use scientific notation to print a given float value? – Jon Purdy Sep 21 '11 at 06:40
  • I will add it in my question. – RajSanpui Sep 21 '11 at 06:40
  • @Jon Purdy: No, i want to parse a string differently if it is an exponential number or if it is any other base. As you know strtol can parse any string to a number, including hex but not exponential, where strtod can. So accordingly i wanted to parse. – RajSanpui Sep 21 '11 at 06:43
  • Sounds like you just defined it: "any number with an `e` in between". If there's no API for this, you can just search for that `e`. – Mysticial Sep 21 '11 at 06:44
  • @Mystical: Searching for an `e` looks clumsy and will take more processor cycles, and this matters a lot if you are coding for a real-time embedded system. And i don't want to go that way. – RajSanpui Sep 21 '11 at 06:46
  • 1
    True, but I'm sure whatever API that implements this is going to do something similar. – Mysticial Sep 21 '11 at 06:46
  • @Mystical: How can you be so sure, without knowing what algorithm that API uses? – RajSanpui Sep 21 '11 at 06:47
  • 1
    You can think of it this way: It's impossible to verify that there is no `e` unless you traverse the entire number. – Mysticial Sep 21 '11 at 06:51
  • 3
    A string is a string, to test if it has a single character in it can only be done 1 way, search for it starting at an index and ending the asearch at another index. If found, do something, if not, do something else. What are you comparing with when you say it will it take more "processor cycles"? If you know a better way to find characters in a string, please let us know! – chown Sep 21 '11 at 06:51
  • @chown: There is no way in re-inventing the wheel, that's what i mean. – RajSanpui Sep 21 '11 at 06:54
  • possible duplicate of [Parsing scientific notation sensibly?](http://stackoverflow.com/questions/638565/parsing-scientific-notation-sensibly) – Michael Foukarakis Sep 21 '11 at 06:57
  • @MichaelFoukarakis: Is it Linux related? – RajSanpui Sep 21 '11 at 07:05
  • @kingsmasher1: Scientific notation is not OS dependent, to the best of my knowledge. – Michael Foukarakis Sep 21 '11 at 07:07
  • 1
    @kingsmasher1, but writing such trivial things cannot be named "reinventing the wheel", as this term talks about more complex situations... you have taken following it far too far. – Griwes Sep 21 '11 at 07:14
  • @Griwes: Look at R's reply, that's a smart one, rather than searching through the strings. – RajSanpui Sep 21 '11 at 10:12
  • 2
    @kingsmasher1, it's slower, as regexps _are_ slower... and have same usability as string searching, in this particular problem. – Griwes Sep 21 '11 at 19:26
  • @Griwes: By the way how many string searching algorithms you are sure of? The brute force approach is the worst one that you suggested. There are other good string searching algorithms and you can never say that even if regex is a string searching one, never use the brute force one. By the way, may i know a) why did you downvote this? b) Why did you remove the Linux tag from this question? Does it make sense removing the tag? Explain. My question is related to Linux and not a mathematical or a C question. – RajSanpui Sep 22 '11 at 13:09
  • @Griwes: And by the way let me tell you as an 18 years old, how many companies and howmany lines of code you have written? As FYI..i have 5+ years industry experience and work for 3 reputed product companies and have 3 research publications in my name. Dude, you need to control your arrogance. Also as you said `Using C in this case can be considered clumsy..` i need this to code my devtool for an embedded system which understands C language, this is not my college homeweok – RajSanpui Sep 22 '11 at 13:18
  • @Griwes: Nonsense; if implemented well (DFA), regular expressions are a near-optimal solution to this type of problem. They will, however, be a bit costly in memory usage. – R.. GitHub STOP HELPING ICE Sep 22 '11 at 14:09
  • @kingsmasher1, the part of arrogance can be also told about you. The fact I am younger than you does not mean that you are smarter than me and write better code, nor your experience mean. Look at comment upvotes under this post and you will see what do I mean. – Griwes Sep 22 '11 at 14:17
  • @R.., ok, I used bad words. Regexp may not be the optimal solution here - and simple parsing is easier to do and understand for everyone. (I don't know what to say about OP's "I need an API", so I won't comment it). – Griwes Sep 22 '11 at 14:19
  • @Griwes: I do write better code, that's why i am hired by one of the best electronics MNCs of the world. They are not fools who hired me. And experience matters a lot in the IT world. I know what is code, what is coding guidelines, and what are the challenges which working in a critical deadline can come (working in a real life project, not college projects) i know what are the different prototypes followed, which a college student might not know. And your inexperience is proved by the fact once you told (without a firm base) regexps are slower. – RajSanpui Sep 22 '11 at 18:51

6 Answers6

4

Exponential numbers don't exist. The number stored in a float or double has the same bit pattern for both for the input 0.01 or 1E-2. Also numbers are not stored in strings. Strings are stored in strings. Therefore if you convert a number into a string you choose a certain transformation either implicitly or explicitly. After the transformation you are working only on a representation of the number but not on the number itself.

If your transformation chooses to convert the number 0.1 into the string "1E-1" or "0.1" or "10^-1" it would be - using your definition - an exponential number only in one of the three cases? That would make sense only in very interesting scenarios, so please take a step back and think about, what the real problem is.

A.H.
  • 63,967
  • 15
  • 92
  • 126
  • I have number said i am converting number to a string, but it is the other way. If i know it is a number and it has an E, then the story ends there. – RajSanpui Sep 21 '11 at 07:13
  • Then just parse it, there are two ways around: parse it (as I answered) or regexp it. Or, if you wish to, convert it to `double` and then check the result... – Griwes Sep 21 '11 at 07:16
3
regex_t re;
regcomp(&re, "^([0-9]+[.]?[0-9]*|[0-9]*[.][0-9]+)[eE][+-]?[0-9]+$", REG_EXTENDED);
if (!regexec(&re, str, 0, 0, 0)) /* It's an "exponential number" */
R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
  • I am not interested in a shell script :-) (It would be easier to convert the the regex to a hex), can we implement regex in C? – RajSanpui Sep 21 '11 at 07:17
  • 1
    That is C. Assuming you have POSIX or a POSIX-compatible regex library at your disposal. – R.. GitHub STOP HELPING ICE Sep 21 '11 at 07:20
  • As Griewes says, do you think this is a slow one? (consuming more machine cycles) and as good as the brute force approach? – RajSanpui Sep 22 '11 at 13:15
  • If you compile the regex (`regcomp`) once then test keep the `regex_t` around and use it for multiple `regexec` tests, it should be very fast, but it will certainly use more memory than the naive approach of just calling `strchr` and `strtod`. If you're planning to convert the string to a number later anyway, just calling `strtod` and a better approach. – R.. GitHub STOP HELPING ICE Sep 22 '11 at 14:06
  • :Thanks again for the nice explanation. – RajSanpui Sep 22 '11 at 18:56
1

I'm assuming that given a string known to be parsable as a number, you want to find out if it's in scientific notation, i.e. has an e in it.

Is using the standard library's strchr function a sufficiently smarter way?

char *num_str = "43e4";

if (strchr(num_str, 'e'))
{
    /* It's in scientific notation! */
    ...
}

More strchr documentation: http://www.gnu.org/software/libc/manual/html_node/Search-Functions.html#index-strchr-549

Edmund
  • 10,533
  • 3
  • 39
  • 57
1

Take a look at lex (or flex).

The lex-rules that I use for recognizing scientific notation numbers are the following:

{DIGIT}*\.{DIGIT}+[eE][+-]?{DIGIT}+  |
{DIGIT}+\.{DIGIT}*[eE][+-]?{DIGIT}+  |
{DIGIT}+[eE][+-]?{DIGIT}+

Where DIGIT is defined as:

DIGIT       [0-9]
Patrick
  • 23,217
  • 12
  • 67
  • 130
1

I don't see what would be wrong by doing a strchr( number, 'e' ) or strchr( number, 'E' ) to check whether you have a scientific notation. To prevent the problems kingsmasher1 explained you should check whether sscanf would accept the string as a valid.

Another approach (not tested) could be comparing the results of sscanf using "%f" and "%g" ("%e"). Note that the e could appear as lower or uppercase letter.

stacker
  • 68,052
  • 28
  • 140
  • 210
1

Step 1: To check whether a string can be interpreted as a double, simply use strtod and examine endptr afterwards:

double strtod(const char *nptr, char **endptr);

Step 2: I doubt there's a pre-existing API for checking whether a floating-point number represented as a string contains an explicit exponent. However, it's such a trivial task that I think you should simply write your own function.

int has_exp(const char* s) {
  while (*s != 0) {
    if (*s == 'e' || *s == 'E') return 1;
    s++;
  }
  return 0;
}
NPE
  • 486,780
  • 108
  • 951
  • 1,012