限制固定输出的尾随零数

Limit number of trailing zeroes for fixed output

本文关键字:输出      更新时间:2023-10-16

我需要一些关于使用C++流进行输出格式化的帮助。我想打印带有固定小数点和最多 2 位尾随的数字。我尝试了以下方法:

#include <iostream>
#include <iomanip>
using namespace std;
int main(int argc, char **argv)
{
  float testme[] = { 0.12345, 1.2345, 12.345, 123.45, 1234.5, 12345 };
  std::cout << std::setprecision(2) << std::fixed;
  for(int i = 0; i < 6; ++i)
  {
      std::cout << testme[i] << std::endl;
  }
  return 0;
}

输出为:

0.12
1.23
12.35
123.45
1234.50
12345.00

但我想拥有

0.12
1.23
12.35
123.45
1234.5
12345

我可以在不使用其他字符串操作的情况下实现这一点吗?

我不知道

合适的操纵器,因此您可以使用:

#include <iostream>
#include <iomanip>
#include <cmath>
template <typename T>
struct Fixed
{
    const T& value;
    const unsigned precision;
    const T significant;
    Fixed(const T& value, unsigned precision)
    : value(value), precision(precision), significant(std::pow(10, precision))
    {}
    void write(std::ostream& stream) const {
        // Adjust stream settings
        std::ostream::char_type restore_fill = stream.fill('0');
        std::ios_base::fmtflags restore_flags = stream.setf(
            std::ios_base::fixed, std::ios_base::floatfield);
        std::streamsize restore_precision = stream.precision(0);
        // Split the floating point into an integral and rounded fractional part
        T integral;
        unsigned long fractional = std::round(significant * std::modf(value, &integral));
        // Determine the length of the fractional part
        unsigned digits = precision;
        while(fractional && fractional % 10 == 0) {
            fractional /= 10;
            --digits;
        }
        // Carry over to the integral part
        if( ! digits && fractional) {
            integral += 1;
            fractional = 0;
        }
        // Output
        stream << integral;
        if(fractional) {
            stream <<  '.' << std::setw(digits) << fractional;
        }
        // Restore stream settings
        stream.precision(restore_precision);
        stream.flags(restore_flags);
        stream.fill(restore_fill);
    }
};
template <typename T>
inline Fixed<T> fixed(const T& value, unsigned precision) {
    return Fixed<T>(value, precision);
}
template <typename T>
inline std::ostream& operator << (std::ostream& stream, const Fixed<T>& value) {
    value.write(stream);
    return stream;
}
int main(int argc, char **argv)
{
  float testme[] = { 0.12345, 1.2345, 12.345, 123.45, 1234.5, 12345 };
  for(int i = 0; i < 6; ++i)
  {
      std::cout << fixed(testme[i], 2) << std::endl;
  }
  return 0;
}

这有效(http://ideone.com/CFcVhu),但它不是那么漂亮......

#include <iostream>
#include <iomanip>
using namespace std;
int main(int argc, char **argv)
{
  float testme[] = { 0.12345, 1.2345, 12.345, 123.45, 1234.5, 12345 };
  //std::cout << std::setprecision(2) << std::fixed;
  for(int i = 0; i < 6; ++i)
  {
      std::cout << ((int)(testme[i]*100.0))/100.0f << std::endl;
  }
  return 0;
}
换句话说

,如果一个数字小于 1000(总是正?),您希望使用 2 个十进制数字表示它,如果它小于 10000,则使用 1 个小数来表示,否则为零。嗯,怎么能编纂这个呢?