不知怎的,我总是假设浮点和整数值的处理方式相同,只有一个会有'。'字符。
所以对于像这样的代码:
auto i = 0100;
std::cout << i;
我得到了预期的输出64
;
但是,当我尝试以下代码时:
auto d = 0100.0;
std::cout << d;
我得到输出100
,这不是预期的。现在有可能浮点部分没有处理前导0.所以我尝试了一些真正应该有效的东西:
auto d = 1.0e-010;
std::cout << d;
由于exponent本身实际上是一个整数值,因此理解八进制值是合理的,但输出为1e-10
。
这是来自标准还是来自g ++(我的编译器)的问题?我将如何编写八进制浮点数?
十六进制似乎表现不同:
auto d = 0x100.0;
提供error: hexadecimal floating constants require an exponent
然而:
auto d = 0x1e3;
std::cout << d;
生成483
。而
auto d = 0x1e0x3;
提供error: unable to find numeric literal operator ‘operator"" x3’
答案 0 :(得分:3)
浮点文字不能用C ++编写的八进制文件。你必须满足于十进制。
标准C ++也不允许使用十六进制浮点文字。但是,C确实(自C99起)和支持它的编译器也可能允许C ++中的十六进制作为语言的扩展。
十六进制似乎表现不同
是。有关如何编写十六进制浮点文字的详细信息,请参阅this answer。
答案 1 :(得分:1)
你可以自己使用C ++ 11的用户自定义文字。
#include <iostream>
#include <cmath>
using namespace std;
long double operator"" _oct (long double oct)
{
int i = 0;
long double rem, fract, decimal = 0.0;
long whole = (long)oct;
fract = oct - whole;
// whole part
while (whole != 0)
{
rem = fmod(whole,10);
whole/=10;
decimal += rem*pow(8,i++);
}
i = 1;
// fractional part
while(fract != 0){
fract *= 10;
rem = round(fract);
decimal += rem*pow(8,-i++);
fract -= rem;
}
return decimal;
}
int main() {
cout << 10.1_oct; //8.125
return 0;
}
答案 2 :(得分:1)
user2079303和blojayble都给出了很好的答案,但两者都有点不完整。所以这里是扩展它们和发现的其他信息。
C ++中没有八进制浮点数...原因
标准没有定义八进制浮点数,编译器遵循这个特殊的规则。前导0
被读作整个部分或指数中的另一个十进制数字。
可能的原因是像0.2
这样的数字含糊不清。大多数人都是这个意思⅕;而如果八进制浮点数是实际的,那么0
是八进制文字(see here)的原因相同,则为1/4。
C ++中没有十六进制浮点数,但是......
...,但是在C.中有很多编译器允许使用它们,但它们有点奇怪。
首先,没有指数部分它们不起作用。所以写0x12a.b3可能不会起作用。
其次,以十六进制表示法e
不是指数,因为它是数字14.因此,使用p
(可能意味着“权力”)。
第三,指数十六进制不是10(当然),但它不是16(由于某种原因)。而它是2.所以0x12.4p3
变为(1×16¹+ 2×16⁰+ 4×16 -1)×2³=(16 + 2 + 1/4)×8 = 146。
在C ++ 11中定义自己的文字是相对简单的
blojayble提供了自己的实现,但我认为最好将其重做为constexpr
。最终结果是以下代码:
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);
}