detecting very long floats?

A

AndrewD

Hi,

Using scanf, is it possible to detect input numbers where the decimal
count is too large?


eg.

scanf("%19lg",&var);

(and if
1.123456789101212314515324234132132
was put in, it would return a certain error value?

Any advice greatly appreciated....

Cheers,
Andrew
 
M

Michael Mair

AndrewD said:
Hi,

Using scanf, is it possible to detect input numbers where the decimal
count is too large?


eg.

scanf("%19lg",&var);

(and if
1.123456789101212314515324234132132
was put in, it would return a certain error value?

Any advice greatly appreciated....

There are several possibilities:
- Use %n to find out how many characters have been read
- Use a scanset format to see whether we continue with valid
characters (e.g. "%[ \t\n]") and check the return value of
scanf()
- Use an inverse scanset format to see that we don't continue with
invalid characters (e.g "%[^0-9eE.+-]") and check the return
value of scanf()

Checking the return value of scanf() and friends _always_ is
a good idea.
scanf() does not always work as intended; see whether a combination
of fgets() and sscanf() does better suit your purposes.


Cheers
Michael
 
R

Richard Bos

AndrewD said:
Using scanf, is it possible to detect input numbers where the decimal
count is too large?
scanf("%19lg",&var);

(and if
1.123456789101212314515324234132132
was put in, it would return a certain error value?

No. It would read as many digits as it needed, and leave the input
stream at that point. A subsequent read would get the next digit. If you
want this feature, a good way is to read a whole line (or as much of it
as you need) using fgets(), and then use strtod() on it.

Richard
 
C

CBFalconer

AndrewD said:
Using scanf, is it possible to detect input numbers where the
decimal count is too large?

eg. scanf("%19lg",&var);

(and if 1.123456789101212314515324234132132
was put in, it would return a certain error value?

I can't answer for individual installations, but as far as I am
concerned anything that inputs floating point values from a stream
should accept all input that fits, even though it will be ignored
as insignificant. All a floating point number contains is an
approximation to the actual value, which is not affected by those
later digits. Once a satisfactory value has been detected and a
decimal point input, it is impossible to have a further underflow
or overflow on additional digits without an exponent clause (eNNN).

A routine to properly handle all possible numerical text input is
not trivial. For an example see the function readxreal in
txtinput.zip, written to supply some of the capabilities of
standard Pascal under Turbo/Borland Pascal, and available at:

<http://cbfalconer.home.att.net/download/txtfiles.zip>
 
C

CBFalconer

Richard said:
No. It would read as many digits as it needed, and leave the input
stream at that point. A subsequent read would get the next digit.
If you want this feature, a good way is to read a whole line (or as
much of it as you need) using fgets(), and then use strtod() on it.

Disagree. I would consider that a low quality implementation. See
my other reply in this thread. I have no idea whether or not the
standard spells this out. Dan Pop, where are you? (He has the
whole thing memorized, and usually provides instant access to well
hidden clauses).
 
E

Eric Sosman

Richard said:
Using scanf, is it possible to detect input numbers where the decimal
count is too large?

scanf("%19lg",&var);

(and if
1.123456789101212314515324234132132
was put in, it would return a certain error value?


No. It would read as many digits as it needed, and leave the input
stream at that point. A subsequent read would get the next digit. [...]

Sounds like a broken implementation, because it would
mis-convert

1.12345678910111213141516171819202122232425262e-10

.... if it didn't read all the way up to (and through) the
exponent.
 
C

Christopher Benson-Manica

CBFalconer said:
standard spells this out. Dan Pop, where are you? (He has the
whole thing memorized, and usually provides instant access to well
hidden clauses).

Is it me, or has he been somewhat scarce of late? He used to be quite
active here...
 
C

CBFalconer

Christopher said:
Is it me, or has he been somewhat scarce of late? He used to be
quite active here...

He was totally missing for a while, and seems to have a different
(less cantankerous) attitude now. His posting address has changed
from Germany back to Switzerland. He may have been ill, or had
other misadventures, but has given no clue.

Nobody noticed I was missing when I had my triple bypass :)
 
M

Mark McIntyre

Nobody noticed I was missing when I had my triple bypass :)

you need to practice being very much ruder, you cretinous moron. Geez,
you call that recent spate of grumpiness grumpy, even ERT would have
realised that wasn't offensive enough.
=;-0



(in case anyone misses the smiley, this is a joke, alright, as anyone
who's been on the recieving end of DP will know...)
 
C

Christopher Benson-Manica

Mark McIntyre said:
(in case anyone misses the smiley, this is a joke, alright, as anyone
who's been on the recieving end of DP will know...)

Anyone who engages his brain will get it :)
 
R

Richard Bos

Eric Sosman said:
Richard said:
AndrewD said:
Using scanf, is it possible to detect input numbers where the decimal
count is too large?
scanf("%19lg",&var);

(and if
1.123456789101212314515324234132132
was put in, it would return a certain error value?

No. It would read as many digits as it needed, and leave the input
stream at that point. A subsequent read would get the next digit. [...]

Sounds like a broken implementation, because it would
mis-convert

1.12345678910111213141516171819202122232425262e-10

... if it didn't read all the way up to (and through) the
exponent.

All the same, this is how Dev-C++ does it; how Pelles C does it; and how
DJGPP does it.

Richard
 
E

Eric Sosman

Richard said:
Richard said:
Using scanf, is it possible to detect input numbers where the decimal
count is too large?

scanf("%19lg",&var);

(and if
1.123456789101212314515324234132132
was put in, it would return a certain error value?

No. It would read as many digits as it needed, and leave the input
stream at that point. A subsequent read would get the next digit. [...]

Sounds like a broken implementation, because it would
mis-convert

1.12345678910111213141516171819202122232425262e-10

... if it didn't read all the way up to (and through) the
exponent.

All the same, this is how Dev-C++ does it; how Pelles C does it; and how
DJGPP does it.

Can't speak for the first two, but the (rather old) DJGPP
version I have reacts in one of two ways:

- For inputs of up to 63 characters, scanf() with "%lf" or
"%lg" swallows all the digits and correctly converts a
trailing exponent; it does not stop in the middle of a
digit stream after converting "enough" input. A subsequent
getchar() returns whatever follows the number, not an
"insignificant digit."

- For longer inputs, scanf() crashes with a SIGSEGV.

Neither behavior seems to match your description ...
 
C

CBFalconer

Eric said:
Richard said:
Eric Sosman said:
Richard Bos wrote:

Using scanf, is it possible to detect input numbers where the
decimal count is too large?

scanf("%19lg",&var);

(and if
1.123456789101212314515324234132132
was put in, it would return a certain error value?

No. It would read as many digits as it needed, and leave the
input stream at that point. A subsequent read would get the
next digit. [...]

Sounds like a broken implementation, because it would
mis-convert

1.12345678910111213141516171819202122232425262e-10

... if it didn't read all the way up to (and through) the
exponent.

All the same, this is how Dev-C++ does it; how Pelles C does
it; and how DJGPP does it.

Can't speak for the first two, but the (rather old) DJGPP
version I have reacts in one of two ways:

- For inputs of up to 63 characters, scanf() with "%lf" or
"%lg" swallows all the digits and correctly converts a
trailing exponent; it does not stop in the middle of a
digit stream after converting "enough" input. A subsequent
getchar() returns whatever follows the number, not an
"insignificant digit."

- For longer inputs, scanf() crashes with a SIGSEGV.

Neither behavior seems to match your description ...

For stream input it is totally unnecessary. All the routine has to
do is a

while (isdigit(ch = getc(f))) continue;
ungetc(ch, f);

in the appropriate circumstances. After which it is well placed to
detect a trailing exponent. There is no need for any UB
whatsoever.
 
R

Richard Bos

Eric Sosman said:
Richard said:
Eric Sosman said:
Richard Bos wrote:


scanf("%19lg",&var);

(and if 1.123456789101212314515324234132132
was put in, it would return a certain error value?

No. It would read as many digits as it needed, and leave the input
stream at that point. A subsequent read would get the next digit. [...]

Sounds like a broken implementation, because it would
mis-convert

1.12345678910111213141516171819202122232425262e-10
All the same, this is how Dev-C++ does it; how Pelles C does it; and how
DJGPP does it.

Can't speak for the first two, but the (rather old) DJGPP
version I have reacts in one of two ways:

- For inputs of up to 63 characters, scanf() with "%lf" or
"%lg"

The specifier wasn't "%lf" or "%lg"; it was "%19lg".

Richard
 
C

CBFalconer

Richard said:
Eric Sosman said:
Richard said:
Richard Bos wrote:

scanf("%19lg",&var);

(and if 1.123456789101212314515324234132132
was put in, it would return a certain error value?

No. It would read as many digits as it needed, and leave the
input stream at that point. A subsequent read would get the
next digit. [...]

Sounds like a broken implementation, because it would
mis-convert

1.12345678910111213141516171819202122232425262e-10
All the same, this is how Dev-C++ does it; how Pelles C does
it; and how DJGPP does it.

Can't speak for the first two, but the (rather old) DJGPP
version I have reacts in one of two ways:

- For inputs of up to 63 characters, scanf() with "%lf" or
"%lg"

The specifier wasn't "%lf" or "%lg"; it was "%19lg".

I think everybody, including me, has missed that. In other words,
the routine is reading precisely the field it was told to read.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,767
Messages
2,569,570
Members
45,045
Latest member
DRCM

Latest Threads

Top