【问题标题】:C++ round a double up to 2 decimal placesC++ 将双精度数舍入到小数点后 2 位
【发布时间】:2014-09-19 02:09:52
【问题描述】:

我无法将 GPA 双精度数舍入到小数点后 2 位。 (例如需要四舍五入的 GPA:3.67924)我目前正在使用 ceil 进行四舍五入,但它目前将其输出为整数 (368)

这是我现在拥有的

if (cin >> gpa) {
    if (gpa >= 0 && gpa <= 5) {
           // valid number

           gpa = ceil(gpa * 100);

           break;
    } else {
           cout << "Please enter a valid GPA (0.00 - 5.00)" << endl;
           cout << "GPA: ";

    }
}

将上面的代码与 3.67924 一起使用将输出 368(这是我想要的,但只是没有整数和小数之间的句点)。我该如何解决这个问题?

【问题讨论】:

  • 乘以 100 并四舍五入后,再除以 100。或者,如果您只需要 打印 保留两位小数,则保持值不变并使用 @987654321 @ 打印时。
  • 标题提到了四舍五入,但问题陈述提到了四舍五入。可以使用 gpa = floor((100.*gpa)+.5)/100 实现舍入。
  • would output 368 (which is what I want, but just without the period between the whole number and the decimals). How can I fix this? 你会这样做gpa /= 100 假设gpadouble

标签: c++ rounding cin ceil


【解决方案1】:

要将双精度数舍入到小数点后 2 位,您可以使用:

#include <iostream>
#include <cmath>

int main() {
    double value = 0.123;
    value = std::ceil(value * 100.0) / 100.0;
    std::cout << value << std::endl; // prints 0.13
    return 0;
}

要四舍五入到 n 位小数,您可以使用:

double round_up(double value, int decimal_places) {
    const double multiplier = std::pow(10.0, decimal_places);
    return std::ceil(value * multiplier) / multiplier;
}

此方法不会特别快,如果性能成为问题,您可能需要其他解决方案。

【讨论】:

  • 在我的具体情况下,我更喜欢使用std::round 而不是std::ceil,但您的解决方案绝对完美。谢谢!
【解决方案2】:

如果只是写屏幕的问题,那么使用四舍五入

std::cout.precision(3);
std::cout << gpa << std::endl;

see

浮点数不能精确表示,因此通过内部舍入该值然后在计算中使用它会增加不精确性。

【讨论】:

    【解决方案3】:

    您不能将双精度数舍入到小数点后两位。双打没有个小数位。它们有二进制位,并且不能与小数位相通。

    如果您想要小数位,则必须使用小数基数,例如使用 printf("%.2f", ...) 格式化输出时。

    【讨论】:

    • 正确,但不一定有帮助 - 例如,希望 最接近 double 到预期的 2 位十进制数字仍然很常见 - 作为之前的步骤做一些其他的计算以尽量减少进一步的错误。
    • @TonyD 他说他想要3.68。与“最近”无关。
    • @TonyDelroy 过早的舍入会导致更多错误。
    • 当您将场景缩小到那些被描述为“过早”的场景时,当然——这个词意味着一个错误。但其他时候更早舍入是使用双精度数计算某些东西的最佳方法,不应被称为“过早的”。例如。如果合同规定折扣是按项目计算的,四舍五入,那么应该在乘以所涉及的项目数量之前完成。 可能具有与特定的两位小数位值最接近的双重表示的价值,即使您知道这不是那么精确。顺便说一句,它可能是准确的 - 例如0.25, 0.75.
    • @TonyDelroy 可以有什么值?当您到达小数基数时,进行四舍五入的时间结束。
    【解决方案4】:

    试试这个。但是您的 cout 语句处于 else 条件,因此它不会为 3.67924 提供所需的输出。

    if (cin >> gpa)
    {     
        if (gpa >= 0 && gpa <= 5) {
            // valid number
    
            gpa = ceil(gpa * 100);
            gpa=gpa/100;
            break;
        } 
        else
        {    
           cout << "Please enter a valid GPA (0.00 - 5.00)" << endl;    
           cout << "GPA: ";
        }
    }
    

    【讨论】:

      【解决方案5】:

      示例:您希望将 56.899999999999 输出为带 2 个小数点的字符串,即 56.89。

      首先,转换它们
      价值 = 56.89 * 1000 = 5689
      系数 = 100
      - 1 个小数点 = 10
      - 2 个小数点 = 100
      - 3 个小数点 = 1000
      等等

      int integerValue;
      int decimal;
      std::string result;
      function ( int value , int factor)
      {
          integerValue= (value / factor) * factor; //(5689 / 100) * 100 = 5600
          decimal = value - integerValue;  // 5689 - 5600;
          result = std::to_string((int)(value/factor) + "." + std::to_string(decimal); 
          // result = "56" + "." + "89" 
          // lastly, print result
      }
      

      不确定这是否有帮助?

      【讨论】:

        【解决方案6】:

        当您尝试在变量中存储最多 n 个十进制值时。 您必须将该值乘以 10^n,然后将其除以 10^n。 之后使用类型运算符在程序中进行操作。 这是示例:-

         float a,b,c,d,sum;
        
         cin>>a>>b>>c>>d; // reading decimal values
        
        sum=(a*b*c*d);
        
        sum=round(sum*100)/100; // here it is for 2 decimal points
        
        if((float)sum < (float) 9.58)
          cout<<"YES\n";
        else
          cout<<"NO\n";  
        

        【讨论】:

          【解决方案7】:
          std::string precision_2(float number)
          {
              int decimal_part = (number * 100) - ((int)number * 100);
              if (decimal_part > 10) {
                  return std::to_string((int)number) + "." + std::to_string(decimal_part);
              } else {
                  return std::to_string((int)number) + ".0" + std::to_string(decimal_part);
              }
          }
          

          可以很好地处理所有正浮点数。稍作修改将使其也适用于 -ves。

          【讨论】:

          • 这是一个老话题,之前已经有很多人回答了。感谢您为社区做出贡献,但不妨将精力集中在最近打开的未回答问题上。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-01-13
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多