c++ 如何在将double转换为字符串时使用科学记数法删除尾随零?

t1qtbnec  于 2023-06-07  发布在  其他
关注(0)|答案(3)|浏览(317)

Live On Coliru
FormatFloat
我尝试用C++实现Golang strconv.FormatFloat()的一个转换。

  1. #include <sstream>
  2. #include <iostream>
  3. #include <string>
  4. #include <iomanip>
  5. using namespace std;
  6. std::string convert_str(double d)
  7. {
  8. std::stringstream ss;
  9. if (d >= 0.0001)
  10. {
  11. ss << std::fixed << std::setprecision(4); // I know the precision, so this is fine
  12. ss << d;
  13. return ss.str();
  14. }
  15. else
  16. {
  17. ss << std::scientific;
  18. ss << d;
  19. return ss.str();
  20. }
  21. }
  22. int main()
  23. {
  24. std::cout << convert_str(0.002) << std::endl; // 0.0020
  25. std::cout << convert_str(0.00001234560000) << std::endl; // 1.234560e-05
  26. std::cout << convert_str(0.000012) << std::endl; // 1.200000e-05
  27. return 0;
  28. }

输出:

  1. 0.0020
  2. 1.234560e-05 // should be 1.23456e-05
  3. 1.200000e-05 // should be 1.2e-05

问题>如何设置输出修饰符,使尾随的零不显示?
strconv.FormatFloat(num,'e',-1,64)
特殊的精度值(-1)用于最小的位数,这样ParseFloat()将准确地返回f。

a0zr77ik

a0zr77ik1#

冒着被严重否决的风险,因为发布了一个C回答了一个**C++**问题...你可以在对sprintf的调用中使用%lg说明符。
cpprefernce
除非要求替代表示,否则将删除尾随零,如果没有小数部分,也将删除小数点字符。
因此,如果你只想在使用科学记数法时删除尾随的零,你可以将convert_str函数改为如下所示:

  1. std::string convert_str(double d)
  2. {
  3. if (d >= 0.0001) {
  4. std::stringstream ss;
  5. ss << std::fixed << std::setprecision(4); // I know the precision, so this is fine
  6. ss << d;
  7. return ss.str();
  8. }
  9. else {
  10. char cb[64];
  11. sprintf(cb, "%lg", d);
  12. return cb;
  13. }
  14. }

对于代码中的三个测试用例,这将给予:

  1. 0.0020
  2. 1.23456e-05
  3. 1.2e-05

从C++20和更高版本开始,std::format class可能会提供一个更现代的替代方案;然而,我还没有完全“跟上”它,所以我不能使用它来给出一个解决方案。其他人可能想这样做。

展开查看全部
hc8w905p

hc8w905p2#

可以使用std::setprecisionstd::defaultfloat操纵器的组合生成所需的输出:

  1. std::cout << std::setprecision(16) << std::defaultfloat
  2. << 0.002 << '\n'
  3. << 0.00001234560000 << '\n'
  4. << 0.000012 << '\n';

Live at:https://godbolt.org/z/67fWa1seo

rmbxnbpk

rmbxnbpk3#

是的,std::scientific不会从科学记数法中删除尾随的零。对于您的特定情况,好消息是cout已经使用科学计数法格式化了0.0001以下的值,并删除了尾随的零。你可以让你的代码像这样:

  1. #include <sstream>
  2. #include <iostream>
  3. #include <string>
  4. #include <iomanip>
  5. using namespace std;
  6. std::string convert_str(double d)
  7. {
  8. std::stringstream ss;
  9. if (d >= 0.0001)
  10. ss << std::fixed << std::setprecision(4); // I know the precision, so this is fine
  11. ss << d;
  12. return ss.str();
  13. }
  14. int main()
  15. {
  16. std::cout << convert_str(0.002) << std::endl; // 0.0020
  17. std::cout << convert_str(0.00001234560000) << std::endl; // 1.23456e-05
  18. std::cout << convert_str(0.000012) << std::endl; // 1.2e-05
  19. return 0;
  20. }
展开查看全部

相关问题