【问题标题】:How to write an octal floating point literal in C++?如何在 C++ 中编写八进制浮点文字?
【发布时间】:2015-12-14 01:09:00
【问题描述】:

不知何故,我一直假设浮点和整数值的处理方式相同,除了一个会有一个“。”字符。

所以对于这样的代码:

auto i = 0100;
std::cout << i;

我得到了预期的输出64

但是,当我尝试以下代码时:

auto d = 0100.0;
std::cout << d;

我得到了输出100,这不是预期的。现在浮点部分可能不处理前导 0。所以我尝试了一些真正应该有效的方法:

auto d = 1.0e-010;
std::cout << d;

由于指数本身实际上是一个整数值,它可以理解八进制值是有道理的,但输出是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’

【问题讨论】:

  • AFAIK 在 C++ 中没有八进制浮点文字。
  • 你尝试过什么(除了这个)?你在哪里卡住了?你研究了什么?
  • 认真的吗?为什么你想要一个八进制浮点文字?
  • 我认为这是一个完全合理的问题。我只是好奇。
  • @KarolyHorvath 一个人研究自己感兴趣的东西。现在可能没有人需要,所以为什么不研究有趣的东西呢?

标签: c++ floating-point octal


【解决方案1】:

浮点文字不能在 C++ 中以八进制编写。你必须满足于小数。

标准 C++ 也不允许十六进制浮点文字。但是,C 可以(自 C99 起)并且支持它的编译器也可能允许在 C++ 中使用十六进制作为该语言的扩展。

十六进制似乎表现不同

是的。有关如何编写十六进制浮点文字的详细信息,请参阅this answer

【讨论】:

    【解决方案2】:

    您可以使用 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;
    }
    

    【讨论】:

      【解决方案3】:

      user2079303blojayble 都给出了很好的答案,但是,两者都有点不完整。因此,这是对它们的扩展以及找到的其他信息。

      C++ 中没有八进制浮点数……这是有原因的

      该标准没有定义八进制浮点数,编译器严格遵守这一特定规则。前导 0 被读取为整个部分或指数中的另一个十进制数字。

      造成这种情况的潜在原因是像0.2 这样的数字不明确。大多数人会说这个⅕;而如果八进制浮点数是现实的话,它会是 ¼,原因与 0 是八进制文字 (see here) 的原因相同。

      C++ 中没有十六进制浮点数,但是……

      ...,但是在 C 中有。这么多编译器允许使用它们,但它们有点奇怪。

      首先,如果没有指数部分,它们就无法工作。所以写 0x12a.b3 可能行不通。

      其次,在十六进制表示法中,e 不是指数,因为它是一个数字 14。因此,使用了p(可能意味着类似于“幂”)。

      第三,十六进制的指数不是 10(当然),但也不是 16(出于某种原因)。而是 2。所以 0x12.4p3 变为 ( 1×16¹ + 2×16⁰ + 4×16⁻¹ ) × 2³ = ( 16 + 2 + ¼ ) × 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);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-02-23
        • 1970-01-01
        • 2014-08-23
        • 2012-06-25
        • 2010-09-11
        • 1970-01-01
        • 1970-01-01
        • 2015-09-07
        相关资源
        最近更新 更多