【问题标题】:Extracting individual digits from a float从浮点数中提取单个数字
【发布时间】:2008-12-03 23:35:54
【问题描述】:

我整天都在努力解决这个问题。我目前正在处理的 C++ 项目需要显示可编辑的值。当前选择的数字显示该数字上方的递增值和下方的递减值。能够将可编辑值作为数字和数字集合引用是很有用的。如果有某种可索引形式的浮点数,那就太棒了,但我一直找不到这样的解决方案。我把这个问题扔出去看看是否有明显的我遗漏的东西,或者我是否应该自己动手。


感谢您的建议!我希望有一个不会从 float -> string -> int 转换的解决方案,但我认为这是摆脱浮点量化问题的最佳方法。我最终选择了 boost::format 并仅引用了字符串的各个字符。与使用 modf 和 fmod 的组合尝试从浮点数中获取数字相比,我看不出这是一个巨大的性能差异(它可能只是在幕后做的,只比我的实现更强大)。

【问题讨论】:

    标签: c++ floating-point extract digits


    【解决方案1】:

    浮点数的内部表示与您看到的不同。你只能施法。

    要投射,请执行以下操作:

    char string[99];
    sprintf(string,"%f",floatValue);
    

    或者看到这个:http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.1

    维基百科文章可以解释更多关于表示的内容:http://en.wikipedia.org/wiki/Floating_point

    【讨论】:

    • 我不会完全称其为铸造,但仍然是一个很好的答案。
    • “cast”形式为 boost::lexical_cast(floatValue);
    【解决方案2】:

    Oh, there are many ways to convert to a string.(虽然我自己更喜欢 snprintf()。)

    或者您可以转换为 int 并使用模数和整数除法提取数字。您可以使用 log{base10} 计算位数。

    (记住:log{baseA}_X / log{baseA}_B = log{baseB}_X。)

    例子:

    #define SHOW(X) cout << # X " = " << (X) << endl
    
    int
    main()
    {
      double d = 1234.567;
    
      SHOW( (int(d)%10000) / 1000 );
      SHOW( (int(d)%1000)  / 100  );
      SHOW( (int(d)%100)   / 10   );
      SHOW( (int(d)%10)           );
      SHOW( (int(d*10)  % 10)     );
      SHOW( (int(d*100) % 10)     );
      SHOW( (int(d*1000)% 10)     );
    
      SHOW( log(d)/log(10) );
    }
    

    虽然你应该使用 static_cast...

    注意指数符号。对于非常大或非常小的数字,您可能会遇到问题。

    浮点数也有四舍五入的问题,可能会让您有些不快。 (这与我们不在两个双打之间使用 operator== 的原因相同。或者为什么您不能依赖 a*b == b*a。根据 a 和 b 的确切值,它们可能会略有不同大约 10^-25。)

    【讨论】:

      【解决方案3】:

      您只能使用 boost::lexical_cast 在字符串和浮点数之间进行转换。但是,您不能直接索引浮点形式 - 它在内部不存储为十进制数字。这可能不是什么大问题。对于您的 UI,您很可能无论如何都会保留数字的字符串形式,并在 getter/setter 中与 float 进行转换。

      【讨论】:

        猜你喜欢
        • 2021-04-12
        • 1970-01-01
        • 2020-08-04
        • 2018-12-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-09-23
        • 1970-01-01
        相关资源
        最近更新 更多