I've been working with cin input recently, and I discovered that strtol needs a radix: long int strtol (const char* str, char** endptr, int base);
, but strtod does not: double strtod (const char* str, char** endptr);
. Obviously, double numbers can be represented in other bases, so why this dichotomy?
2 回答
strtol
is usually used with base
set to 0
or 10
. base==0
causes it to treat the string as a C integer constant. It uses a leading 0
for octal, or a leading 0x
or 0X
for hexadecimal; otherwise, it's assumed to be decimal. With base==10
, it doesn't recognize anything other than decimal (which is more user-friendly; most uses won't expect an input of 010
to be interpreted as 8
).
Floating-point numbers can be represented in bases other than decimal, but C++ only supports decimal. (C added support for hexadecimal floating-point in the 1999 ISO C standard, but C++ has not adopted this feature.)
strtod
could have had an option to interpret, for example, 1.4
as a base-8 constant, equal to 1.5
decimal -- but there just isn't enough demand to justify it.
Integer input might usefully be written in bases 2, 8, 10, and 16, and strtol
permits other bases just because it's easy to do so. Floating-point input is rarely anything other than decimal (and the syntax of a C hexadecimal floating-point constant is unambiguous so there's no need to specify it).
The reason for this is there is no way in C++ to express a floating point value in a different base other than base 10. From [lex.fcon] 2.13.4(1)
A floating literal consists of an integer part, a decimal point, a fraction part, an e or E, an optionally signed integer exponent, and an optional type suffix. The integer and fraction parts both consist of a sequence of decimal (base ten) digits. [...]
emphasis mine
If floating point numbers can only be expressed in base 10 then there is no reason to have to specify the base. integer types on the other hand can be expressed in different basses to strtol
deals with that.