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?

- 86
- 11
-
Can you give an example of a double expressed in another base? – Panagiotis Kanavos Oct 12 '15 at 15:44
-
While doubles _could_ be represented in other bases, they very rarely _are_, whereas (at least among programmers) longs/ints etc. reasonably often are. Also, think of it as `strtol` _can_ accept a radix (i.e. to provide extra functionality) ... it didn't _need_ to. – TripeHound Oct 12 '15 at 15:46
-
@PanagiotisKanavos Something like (1.1)_2 == (1.5)_10 I guess. But, OP, I never saw anyone do this in the real world, so I would guess that simply no one cared, so no one proposed to put it in. – Baum mit Augen Oct 12 '15 at 15:46
-
Fair enough. That answers my question. If someone wants to make an answer, I'll mark it. – Defenestrator Oct 12 '15 at 15:48
2 Answers
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).

- 254,901
- 44
- 429
- 631
-
@Defenestrator: Please read the update; I initially glossed over some differences between C and C++. – Keith Thompson Oct 12 '15 at 15:55
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.

- 171,901
- 28
- 288
- 402
-
hmmm ... `std::cout << 0x0.3p10 << std::endl;` seems to work. I know that floating point hex literals were added to C99, I assumed that modern C++ would include them as well. – D.Shawley Oct 12 '15 at 15:54
-
@D.Shawley It may be an extension. GCC like to include C features like VLA's that are not standard in C++. BTW it will not compile with MSVS 2015. also see: http://coliru.stacked-crooked.com/a/36bad535794a37d7 – NathanOliver Oct 12 '15 at 15:58