以下代码:

#include <iostream>
#include <ios>

int main() {
    auto mod = 1e9+7;
    std::cout << mod << '\n';
    std::cout << std::fixed << mod << '\n';
}

输出:

1e+009
1000000007.000000

我认为在这种情况下,mod是一个浮点数,因此第一个给出 1e+009 作为输出,这可能是由于浮点精度。但是在使用之后std::fixed,为什么输出不是 1000000000.000000 ?

16

  • 8
    为什么您期望得到这样的输出?


    – 

  • 8


    – 

  • 3
    我看了看水晶球,它告诉我你很快就要解决一个竞赛编程问题,它要求你给出模 1000000007 的结果。请避免使用浮点数,它会给你带来比以一种有趣的方式打印结果更多的麻烦。


    – 

  • 4
    任何要求结果模 1000000007 的“挑战”都不应该先计算结果,然后再进行模数运算。相反,你应该先做数学运算,看看如何直接计算结果。所以这是一个数学挑战,而不是教你任何编码。


    – 

  • 5
    using namespace std; #define mod 1e9+7与之前的评论似乎表明你没有从好的来源学习 C++。(你从哪里学习 C++?)。不要使用using namespace std;,如果需要常量,请使用static constexpr double mod = 1.0e9+7;但也要先了解浮点计算的局限性,这是一个轻松但富有洞察力的视频


    – 



最佳答案
1

1e9 + 7

这个数字可以在 中精确表示double,这里没有精度损失。

但是,使用 打印时std::cout << mod,会使用默认精度(即 6 位小数)打印。因此,不会打印 7。

您可以调整std::cout使用std::setprecision操纵器的精度:

#include <iostream>
#include <iomanip>

int main() {
    std::cout << std::setprecision(10) << mod << '\n';
}

将打印1000000007

4

  • 我注意到的一件事是,问题的初始输出 ( 1e+009) 是科学计数法。你能在答案中保留这种格式,只是精度更高吗?(这可以作为显示std::setprecision(10)本身的效果的补充。)


    – 


  • 实际上并不能保证1e9+7可以用 表示double。对于特定的浮点表示(例如 IEEE)这是正确的,但对于其他浮点表示则不然。C++ 标准不要求使用 IEEE 浮点,并且现实世界中的实现并不使用 IEEE。


    – 

  • @Peter:1,000,000,007 可以精确表示double。C++ 通过各种参考资料从 C 继承了浮点类型的一些最低要求(2 规范性参考资料 [intro.refs] 1:“本文引用了以下文档,其部分或全部内容构成了本文档的要求……”),并且 C 所需的精度足以保证 1,000,000,007 可以表示。


    – 


  • @IlyaPopov 谢谢你,你能否确认 fixed 是否除了在这里删除科学计数法之外还能做更多的事情(我对编码很陌生,找不到任何可以澄清“fixed”用法的在线资源)


    –