Fibonacci number

K

Keith Thompson

CBFalconer said:
It still is. The leading '0' signals an octal base.

It signals an octal base in a literal in C source code. It's not
obvious that user input should have the same syntax as program source
code.

For a program whose end users are likely to be non-programmers,
interpreting 012 as an octal number is counterintuitive. OTOH, if the
program is going to be used only by its author or by fellow
programmers, being able to use octal and hexadecimal input can be
quite handy.
 
D

Dan Pop

In said:
Doug's claim is that 012 = 10 was around "well before C appeared."
I'm not saying he's wrong (in fact, I think he's right), but I, too,
would be curious where "leading 0 means octal" cam e from, if not from
C.

From octal dumps, that were quite popular on certain machines at the time
(most, if not all the DEC machines preceding the VAX had octal as their
"native" base). The PDP-11 is also a "natively" octal architecture: 8
general purpose registers and 8 addressing modes lead to the following
encoding for the two operand instructions: BOSSDD, where B was the byte
flag (0 for word instructions, 1 for byte instructions), O was the actual
opcode, SS was the register and addressing mode of the source operand,
DD was the register and addressing mode of the destination operand.

A byte in octal was written as a 3-digit number, just as it is written as
a 2-digit number in hex, even when one digit would be enough. So, when
one saw 012, he reacted as most of us would react today at 0A.

Dan
 
D

Dan Pop

In said:
Apart from exponential notation for reals, I see no problem
building iron-clad numeric input parsers with one-char look
ahead.

Dealing with overflow without invoking undefined behaviour is the most
challenging part.

Dan
 
D

Douglas A. Gwyn

Dan said:
And this is a deficiency of the C standard that the committee doesn't
bother to fix. Why should each robust C application have to invent its
own wheel?

What constitutes really good input checking and validation
is heavily application-dependent.
 
D

Dave Hansen

In said:
Doug's claim is that 012 = 10 was around "well before C appeared."
I'm not saying he's wrong (in fact, I think he's right), but I, too,
would be curious where "leading 0 means octal" cam e from, if not from
C.

From octal dumps, that were quite popular on certain machines at the time [...]

A byte in octal was written as a 3-digit number, just as it is written as
a 2-digit number in hex, even when one digit would be enough. So, when
one saw 012, he reacted as most of us would react today at 0A.

I learned and used octal several years before I dealt with hex much.
ISTR that most or all octal numbers on dumps began with zero. This is
why I said I thought Doug might be correct.

But I was hoping someone would say "PDP-1 MACRO Assembler [or some
other language translator] defined a similar syntax" as support for
the statement.

BCPL maybe?

Regards,

-=Dave
 
P

P.J. Plauger

It signals an octal base in a literal in C source code. It's not
obvious that user input should have the same syntax as program source
code.

For a program whose end users are likely to be non-programmers,
interpreting 012 as an octal number is counterintuitive. OTOH, if the
program is going to be used only by its author or by fellow
programmers, being able to use octal and hexadecimal input can be
quite handy.

Safety tip: Use 10 as the third (base) argument to strtoul, so 012
converts to 12. Don't use 0 as the base argument, since that's the
*only* form that lets the input prefix determine the base.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
D

Douglas A. Gwyn

Keith said:
It signals an octal base in a literal in C source code. It's not
obvious that user input should have the same syntax as program source
code.

While that is true in general, the practice harks back to
(at latest) responses to interactive prompts from DEC SYSGEN
programs, where the radix for input was under control of
the person entering the data, using 0 prefix for octal.
... if the
program is going to be used only by its author or by fellow
programmers, being able to use octal and hexadecimal input can be
quite handy.

Yes, that was the idea. A size, for example, might be
thought of in decimal or in some binary-related readix,
depending on how it was obtained.

In a similar vein, there are programs such as Unix "dd"
where sizes can be specified in bytes, "blocks", "Kbytes",
etc. through use of suffixes.

And of course as far back as early Fortran, numeric input
was allowed to optionally be expressed in a form of
"scientific notation".

Whether these are good ideas or not depends on many factors,
and is not something that the C standard is in a position to
determine.
 
L

lawrence.jones

In comp.std.c P.J. Plauger said:
Safety tip: Use 10 as the third (base) argument to strtoul, so 012
converts to 12. Don't use 0 as the base argument, since that's the
*only* form that lets the input prefix determine the base.

But again, that's application dependent. For some applications, being
able to input octal or hex in addition to decimal is definitely a
feature, not a bug.

-Larry Jones

Oh, now YOU'RE going to start in on me TOO, huh? -- Calvin
 
D

Dennis Ritchie

Roc said:
Someone provide the history on how 012 was interpreted as 10, please?

Most directly, from B. Not from BCPL. Richards's 1967 manual,
which we had, used an initial underlined 8 in its canonical syntax
to indicate an octal constant.
Someone once sent me the actual examples from this manual--
they're missing from my copy--but I've misplaced that reference.

In the BCPL compiler listings I have, it is initial $8 that signals
an octal constant; in the Richards & Whitby Strevens book
it is # (#X marks hexadecimal).

Dennis
 
W

Wojtek Lerch

P.J. Plauger said:
It is.


It seems *to you* that it isn't. I kinda like it.


Or skip it yourself. Why is that so hard?

Because you might not have a guarantee that the current locale is "C"?

It seems reasonable that in other locales, strtoul() might recognize
additional spellings of the negative sign, or accept the sign after the
digits. How do I tell the difference between 2 and -4294967294 then?
 
C

CBFalconer

Dan said:
Dealing with overflow without invoking undefined behaviour is
the most challenging part.

Something along the lines of:

overflow = partial = 0;
while (getavaliddigit()) {
.... form input digit ....
if ((partial < CRITERION) ||
(MAX - digit) / base) <= partial))
partial = base * partial + digit;
else {
overflow = 1;
partial = MAX;
}
}
putback(ch); /* beware complications from EOF and unget */

does not require any hardware overflow detection, and will gobble
up a stream of digits.
 
R

Richard Bos

Wojtek Lerch said:
Because you might not have a guarantee that the current locale is "C"?

It seems reasonable that in other locales, strtoul() might recognize
additional spellings of the negative sign, or accept the sign after the
digits. How do I tell the difference between 2 and -4294967294 then?

7.20.1.4 #6: In other than the "C" locale, additional locale-specific
subject sequence forms may be accepted.

IOW, if you're not in the "C" locale, you don't know jack about the
subject sequence anyway, so there's no way for you to tell whether
_anything_ is positive or negative - but more importantly, you don't
even know if anything is an integer in the first place.

But there's still a reasonable way around this: _first_ scan the string
with strtol(). If the result is negative, the subject sequence contained
a minus sign; this is true regardless of whether the number fits a long,
because on negative overflow, strtol() returns LONG_MIN, which is also
negative.

Richard
 
D

Dan Pop

In said:
What constitutes really good input checking and validation
is heavily application-dependent.

When dealing with numeric input, all applications have the same
requirements: the input was correct according to the specifications of
the corresponding type. If the application wants further restrictions
(e.g. values in a subrange of type_MIN..type_MAX), these can be
trivially implemented once you know the input was valid for its
intended type.

Dan
 
D

Dan Pop

In said:
Actually, scanf is quite good and well designed. I have only two
complaints about it:

1. Undefined behaviour on numeric input overflow. Making the conversion
fail would have been a lot more useful.

2. No escape sequence for specifying a null character in a scanset (\0
would terminate the format string).

I somehow forgot the third one: no way to dynamically specify maximum
field widths, like the asterisk in printf formats.

The workaround is to build the whole format string at run time, but
this destroys the code readability, because you have to imagine how
the format string would look like, instead of simply looking at it.

Dan
 
D

Dan Pop

In said:
But again, that's application dependent. For some applications, being
able to input octal or hex in addition to decimal is definitely a
feature, not a bug.

This whole subthread was started by the complaint that 012 is interpreted
as an octal number, which I failed to understand.

If you don't want this to happen, use base 10 and it won't happen.
If you use "base" 0, it is precisely because you want this to happen.

Programs using "base" 0 should warn the users about the expected input
formats and their semantics.

Dan
 
W

Wojtek Lerch

Richard said:
7.20.1.4 #6: In other than the "C" locale, additional locale-specific
subject sequence forms may be accepted.

IOW, if you're not in the "C" locale, you don't know jack about the
subject sequence anyway, so there's no way for you to tell whether
_anything_ is positive or negative - but more importantly, you don't
even know if anything is an integer in the first place.

Exactly: all I can possibly know is what strtoul() tells me. If
strtoul() tells me that the string a person entered is a
representation of the number 2 in the current locale, I have no choice
but to trust that.

Unless, of course, I parse the string myself and notice that it's
"-4294967294". But if I'm not in the "C" locale, I have no reliable
way of catching all such misunderstandings.
But there's still a reasonable way around this: _first_ scan the string
with strtol(). If the result is negative, the subject sequence contained
a minus sign; this is true regardless of whether the number fits a long,
because on negative overflow, strtol() returns LONG_MIN, which is also
negative.

That's a nice idea, but I think it might not work with some
conceivable (albeit wierd) implementations. Imagine, for instance,
that in some locale, the additional forms of subject sequences contain
a prefix that specifies whether the number is signed negative, signed
non-negative, or unsigned, and strtol() rejects the unsigned ones as
invalid. Wouldn't that be conforming?
 
R

Richard Bos

That's a nice idea, but I think it might not work with some
conceivable (albeit wierd) implementations. Imagine, for instance,
that in some locale, the additional forms of subject sequences contain
a prefix that specifies whether the number is signed negative, signed
non-negative, or unsigned, and strtol() rejects the unsigned ones as
invalid. Wouldn't that be conforming?

I'm not sure, but I doubt it. Even if it is, when it returns a negative
value, the subject sequence is signed negative. Invalid subject
sequences must return 0.

Richard
 
W

Wojtek Lerch

Richard said:
I'm not sure, but I doubt it. Even if it is, when it returns a negative
value, the subject sequence is signed negative. Invalid subject
sequences must return 0.

Sorry, that wasn't a very good example... But what about this one: a
suffix that is interpreted as a negative sign by strtol(), but not
recognized by strtoul(). Can you find any words in the standard that
forbid this?...
 
R

Richard Bos

suffix that is interpreted as a negative sign by strtol(), but not
recognized by strtoul(). Can you find any words in the standard that
forbid this?...

Not words, exactly, but it does seem to imply that. All four of
strtol(), strtoul(), strtoll() and strtoull() share a paragraph, and
that paragraph mentions "the" subject sequence, singular. The only
difference that is explicitly mentioned is that between the type to
which these functions convert the subject sequence.

Richard
 

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,772
Messages
2,569,593
Members
45,111
Latest member
VetaMcRae
Top