以科学记数法打印 cpp_dec_float ,不带尾随零

2024-02-16

我在用着cpp_dec_float http://www.boost.org/doc/libs/1_55_0/libs/multiprecision/doc/html/boost_multiprecision/tut/floats/cpp_dec_float.html对于任意精度,这很棒,但我无法弄清楚如何打印所有有效数字。

例如,使用此代码进行设置

using boost::multiprecision::cpp_dec_float;
typedef boost::multiprecision::number<cpp_dec_float<100>> mp_type;

mp_type test_num("7.0710678118654752440084436210484903928483593768847403658833986900e-01");

如果我只是打印

std::cout << std::scientific << test_num << std::endl;

结果是7.071068e-01,这样就可以了。

如果我选择分手

std::cout << std::setprecision(std::numeric_limits<mp_type>::digits) << std::scientific << test_num << std::endl;

I get 7.0710678118654752440084436210484903928483593768847403658833986900000000000000000000000000000000000000e-01。我很高兴没有失去精度,但它在空间上不是很保守。

有没有办法使用现有工具删除尾随零而不损失任何精度?如果不是,如何从结果字符串中删除尾随零?

如果现有的工具能够满足我的意图,如何才能cpp_dec_float以科学记数法输出,而不会丢失精度并将尾随零删除到字符串中?我只能找到流示例 http://www.cplusplus.com/reference/ios/scientific/.

Closer

感谢mockinterface,我更接近了。

我已将代码更改为:

using boost::multiprecision::cpp_dec_float;
typedef boost::multiprecision::number<cpp_dec_float<0>> mp_type;
mp_type test_num("7.0710678118654752440084436210484903928483593768847403658833986900e-01");
std::cout << test_num.str(0, std::ios_base::scientific) << std::endl;

具有潜在的无限长度;但是,这是打印的:

7.0710678118654752440084436210484903928480e-01

这很接近但看起来很奇怪。在里面source http://code.woboq.org/boost/boost/boost/multiprecision/cpp_dec_float.hpp.htmlmockinterface 如此慷慨地向我指出,我发现了这些行

if(number_of_digits == 0)
    number_of_digits = cpp_dec_float_total_digits10;

这对我来说意味着它应该考虑所有有效数字,基本上输出输入的内容,因为长度不受限制。

我检查了source http://code.woboq.org/boost/boost/boost/multiprecision/cpp_dec_float.hpp.html#_ZN5boost14multiprecision8backends13cpp_dec_float28cpp_dec_float_total_digits10E for cpp_dec_float_total_digits10,我无法确定它到底是什么;不过,我确实找到了似乎定义它的代码部分。

private:
   static const boost::int32_t cpp_dec_float_elem_digits10 = 8L;
   static const boost::int32_t cpp_dec_float_elem_mask     = 100000000L;

   BOOST_STATIC_ASSERT(0 == cpp_dec_float_max_exp10 % cpp_dec_float_elem_digits10);

   // There are three guard limbs.
   // 1) The first limb has 'play' from 1...8 decimal digits.
   // 2) The last limb also has 'play' from 1...8 decimal digits.
   // 3) One limb can get lost when justifying after multiply,
   //    as only half of the triangle is multiplied and a carry
   //    from below is missing.
   static const boost::int32_t cpp_dec_float_elem_number_request = static_cast<boost::int32_t>((cpp_dec_float_digits10 / cpp_dec_float_elem_digits10) + (((cpp_dec_float_digits10 % cpp_dec_float_elem_digits10) != 0) ? 1 : 0));

   // The number of elements needed (with a minimum of two) plus three added guard limbs.
   static const boost::int32_t cpp_dec_float_elem_number = static_cast<boost::int32_t>(((cpp_dec_float_elem_number_request < 2L) ? 2L : cpp_dec_float_elem_number_request) + 3L);

public:
   static const boost::int32_t cpp_dec_float_total_digits10 = static_cast<boost::int32_t>(cpp_dec_float_elem_number * cpp_dec_float_elem_digits10);

能否确定有效位数并将其用作第一个参数boost::multiprecision::cpp_dec_float::str()?


事实证明这是一项艰难的任务。

简而言之:cpp_dec_float 中没有这样的功能。更糟糕的是,cpp_dec_float 不跟踪已设置的有效位数,因此没有“便宜”的方法来找到打印分数所需的长度。

Ideas:

  • 对于某些边界情况(例如 123.000000000000001),可以取小数部分倒数的 log10 + 整数部分的 log10。这完全不能普遍适用。

  • 如果您想使用实现细节,您可能会在后端数组中找到“最后居住”的元素,并进行数学计算。然而,这非常复杂(需要修改cpp_dec_float.hpp和大量的测试)。

  • 最后,我观察到当前的实现.str()显然使zero努力做到高效。完全没有。

总而言之,我有以下建议。任何一个

  1. 切换到gmp后端(如果你能负担得起)。笔记

    • 这不是十进制浮点表示 AFAICT
    • 这需要链接一个额外的库(libgmp)
    • gmp_float does虽然有任意精度,and
    • it's str()执行does考虑尾数中零的重要性

    See it 住在科里鲁 http://coliru.stacked-crooked.com/a/27c0c45e77187bae

    #include <boost/multiprecision/number.hpp>
    #include <boost/multiprecision/gmp.hpp>
    #include <iostream>
    
    namespace mp = boost::multiprecision;
    
    int main()
    {
        typedef mp::number<mp::gmp_float<100>> mp_type;
        mp_type test_num("7.071067811865475244008443621048490392848359376884740365883398690000000000000000000e-01");
    
        std::cout << test_num.str(0, std::ios_base::scientific) << '\n';
    }
    

    Prints 7.071067811865475244008443621048490392848359376884740365883398690e-01无需采取进一步行动。

  2. 如果这不是一个选项,我只需对输出进行后处理,删除尾随零:

    template <typename T>
    std::string to_pretty_string(T const& v)
    {
        std::string s = v.str(0, std::ios_base::scientific);
        assert(s.length()>3); // min: 0.e
        switch (s[0])
        { // normalized scientific always has #.####### form of mantissa
            case '-':
            case '+': assert(s[2] == '.'); break;
            default:  assert(s[1] == '.'); break;
        }
    
        auto exp = s.find('e');
        if (std::string::npos != exp && exp > 0)
        {
            for(size_t pos = exp-1; pos; --pos)
            {
                if (s[pos] != '0')
                {
                    // remove run of 0s if applicable
                    s.erase(pos+1, exp-pos-1); 
                    break;
                }
            }
        }
        return std::move(s);
    }
    

See it 住在科里鲁 http://coliru.stacked-crooked.com/a/adebdde84a656b42 again

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

以科学记数法打印 cpp_dec_float ,不带尾随零 的相关文章

随机推荐

  • EasyPHP 16.1 自动启动 httpd 和 mysql

    我很困惑 因为每次运行 EasyPHP 时我都需要通过仪表板来启动 http 和 mysql 服务器 真的很烦人 有没有办法设置easyphp自动启动http和mysql 现在 需要点击 10 次才能运行网站 而不是 14 1 中的 3 次
  • Google Colab 驱动器安装(带下划线)无法正常工作

    直到昨天 1月20日 我还可以连接到另一个谷歌驱动器帐户 使用drive mount 但是当我今天尝试这个时 谷歌colab向我显示了这个错误 from google colab import drive drive mount conte
  • 在两个坐标空间之间变换对象

    所以我正在阅读 图形和游戏开发的 3D 数学入门 一书 我几乎没有数学背景 我终于开始掌握矢量 矩阵数学 这是一种解脱 但是 是的 总有一个但是 我无法理解对象从一个坐标空间到另一个坐标空间的转换 作者在书中举了一个例子枪击汽车 图 htt
  • firebase auth 在安装过程中要求授权代码

    我正在尝试安装 firebase 身份验证 它要求在 cli 中提供授权代码 无论我如何检查 我都没有看到任何授权代码 我在 firebaseConfig 中提供了 Web api 密钥等 我是否遗漏了一些明显的东西 这是我在 cli 中的
  • Rails 路线 - 斜杠字符与哈希字符

    在 url 和 Rails 路由中 使用斜杠字符与井号 井号 字符有什么区别 这些工作 get static pages about get about to static pages about as about 这些不 get stat
  • MVC - 一个模型可以由几个其他模型组成吗? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 当同步/异步与串行/并发队列混合时,调度程序如何工作?

    在 Grand Central Dispatch 中 调度程序如何处理不同的队列 serial and concurrent 当使用dispatch sync函数和dispatch async功能 首先我们需要两种类型queue one s
  • 使用 Spring Data Mongo 的 ObjectId 进行 Facet + 聚合查询问题

    我正在开发Spring Boot Spring Data Mongo 我真的很努力 public Page
  • 命令组合设计模式

    有没有人有 Ruby 中使用组合命令的好例子 这是我在各种设计模式文献中看到的一种设计模式混合体 听起来相当强大 但一直无法找到任何有趣的用例或代码 受到总体想法的启发这篇博文中的示例模式实现 http blog ashwinraghav
  • INVD指令有什么用?

    The x86 INVD http faydoc tripod com cpu invd htm使缓存层次结构无效without显然 将内容写回内存 我很好奇 这样的指令有什么用 鉴于人们对各个缓存级别中可能存在哪些数据的控制非常少 甚至对
  • jsp页面中使用spring bean的教程

    我不熟悉与 HTML 交付相关的技术 例如 JSP 但我知道基本概念 在我的应用程序中 我使用 Spring Beans 和 Spring Security 以及 Blaze DS 通过 AMF 协议与 Flex 应用程序进行通信 一切都很
  • Google 地图 API 中的建议路线选项?

    我需要显示源和目的地之间的多条路线 例如 如果我选择源和目的地 我就能够找到一条路线 但就像在谷歌地图中一样 我们有一个建议的路线选项 我需要实现它 但我所有的尝试都失败了 请找到下面的代码 例如 它显示源和目的地之间的单个路由 如果我错过
  • 在 php 中测量字符串大小(以字节为单位)

    我正在为一个门户网站做一个房地产提要 它告诉我字符串的最大长度应该是 20 000 字节 20kb 但我以前从未遇到过这个 我怎样才能测量byte的大小varchar string 所以我可以做一个 while 循环来修剪它 您可以使用 m
  • java中的资源是什么?为什么使用完后要关闭它?

    java中 资源 一词的含义是什么 尽管垃圾收集器在jvm中运行 为什么我们在使用后必须关闭它 为什么我们必须在finally块中编写资源清理代码 资源是数量有限的东西 例如数据库连接和文件描述符 GC 释放内存 但您仍然必须释放资源 例如
  • Nestjs ConfigModule.forRoot() 异步

    我想从具有 REST API 的配置服务器加载 Nestjs 中的配置 以允许集中式应用程序配置 但是 ConfigModule forRoot 函数没有异步版本 因此配置返回为undefined 有没有办法解决 通过创建返回 Nest C
  • 如何将系统音量与媒体播放器应用程序同步

    我刚刚开发了一个简单的媒体播放器 可以播放歌曲 并且有一个可以调节歌曲音量的搜索栏 这是我的代码 public class MainActivity extends AppCompatActivity Button playBtn Seek
  • 在 Windows 中使用两只鼠标执行完全不同的操作

    我目前正在尝试开发一个应用程序 以使用两只鼠标在 Windows 中执行完全不同的操作 然而 在花了几天时间之后 我开始怀疑使用 Windows API 是否可以实现我想要做的事情 由于我远不是 Windows API 方面的专家 因此我想
  • 是否可以使用 jQuery.attr() 函数设置多个数据属性?

    这有效 myObj attr data test 1 num1 myObj attr data test 2 num2 但这并没有 myObj attr data test 1 num1 data test 2 num2 我在这里错过了一些
  • 当 Firebase 函数发送时,时间戳会在 BigQuery 上返回错误

    我正在尝试从 Firebase 函数将时间戳字段发送到 BigQuery 我正在发送 admin firestore FieldValue serverTimestamp BigQuery 上的字段是 TIMESTAMP 类型 我收到一个错
  • 以科学记数法打印 cpp_dec_float ,不带尾随零

    我在用着cpp dec float http www boost org doc libs 1 55 0 libs multiprecision doc html boost multiprecision tut floats cpp de