Somehow i have always assumed that floating point and integer values are processed the same except one would have a '.' character.
So for the code like this:
auto i = 0100;
std::cout << i;
I get the expected output 64
;
However, when i try the following code:
auto d = 0100.0;
std::cout << d;
I get output 100
, which is not what was expected. Now it is possible that the floating point part does not deal with a leading 0. So i have attempted something which really should have worked:
auto d = 1.0e-010;
std::cout << d;
Since exponent is actually an integer value itself, it made sense that it would understand the octal value, but the output was 1e-10
.
Is this an issue that comes from the standard or from g++ (my compiler)? How would i go about writing an octal floating point number?
Hexadecimal seem to behave differently:
auto d = 0x100.0;
Gives error: hexadecimal floating constants require an exponent
However:
auto d = 0x1e3;
std::cout << d;
produces 483
. While
auto d = 0x1e0x3;
Gives error: unable to find numeric literal operator ‘operator"" x3’
user2079303 and blojayble have both given excellent answers, however, both were a bit incomplete. So here is expansion on both of them and additional information which was found.
There are no octal floating point numbers in C++… for a reason
The standard does not define octal floating point numbers, and compilers obey this particular rule to the letter. Leading 0
is read as just another decimal digit in the whole part or in the exponent.
Potential reason for this is the ambiguity of the number like 0.2
. Most people would mean by this ⅕; while if octal floating point numbers were a reality it would be ¼ for the same reason why 0
is an octal literal (see here).
There are no hexadecimal floating point numbers in C++, but…
…, but there are in C. So many compilers allow one to use them, but they are a bit weird.
Firstly, they do not work without an exponent part. So writing 0x12a.b3 will likely not work.
Secondly, in hexadecimal notation e
is not an exponent, since it's a digit 14. Therefore, p
is used (probably meaning something like "power").
Thirdly, the exponent is hexadecimal is not 10 (of course), but it is not 16 (for some reason). Rather it is 2. So 0x12.4p3
becomes ( 1×16¹ + 2×16⁰ + 4×16⁻¹ ) × 2³ = ( 16 + 2 + ¼ ) × 8 = 146.
It is relatively trivial to define own literals in C++11
blojayble has provided own realisation, but i thought that it would be best to redo it making it into a constexpr
. The end result is the following code:
constexpr unsigned long long operator"" _oct(unsigned long long l)
{
return
(l < 9) ? l :
operator"" _oct(l/10)*8 + l%10;
}
constexpr long double operator"" _oct(long double d)
{
return
(d == 0) ? 0.0 :
(d < 1) ? 0.125*(((int)(d*10)) + operator"" _oct(d*10-((int)(d*10)))) :
operator"" _oct((unsigned long long)d) + operator"" _oct(d-(unsigned long long)d);
}