如何将总成本(双倍)舍入到最近的inetegrs

时间:2016-09-06 18:05:51

标签: c++

我试图在网上搜索类似的问题,但非对我有用。 我最接近的是"如果.5之前的数字是奇数向上,如果向下舍入13.5转为14但12.5转为12"。

来到这个问题:

我只需用公式计算用餐后的总量;

总金额= mealamount + mealamount * tip%+ mealamount * tax%

我想出了这段代码(仅粗略)

#include<iostream>
#include<math.h>
#include <iomanip>
using namespace std;
int main () {
    double mealCost;
    double total=0;
    double tipp,taxx=0;
    cin>>mealCost;
    int tip;
    cin>>tip;
    tipp=(tip*mealCost)/100;
    int tax;
    cin>>tax;
    taxx=(tax*mealCost)/100;
    total=mealCost+tipp+taxx;
    cout << fixed << showpoint;
    cout << setprecision(2);
    cout<<total<<endl;
    return 0;
}

但输入为10.75(mealamonut),17(tip%),5(tax%)。 我得到的价值是12.50 如果我使用

int totalSum = std::round(total);

它被转换为12 但我的要求是13。 如何实现这一目标?

如果存在,我找不到任何重复的问题 请提一下。

5 个答案:

答案 0 :(得分:4)

有多种方法可以将双精度转换为整数。你有多种回合。检查herestd::round, std::lround, std::llround

另一方面,如果你想做的不是四舍五入,而是将分数排除在一个方向上,那么std::ceil总是更高,而std::floor总是更低

请记住包含<cmath>,而不是<math.h>。后者适用于C,而非C++

答案 1 :(得分:0)

您可以使用cmath头文件中定义的std::ceil()std::floor()来实现目标。

答案 2 :(得分:0)

您正在尝试总是向上舍入,因此您需要使用ceil()函数。 Ceil是天花板的缩写,还有地板功能。天花板上升,地板下降,这是一个尝试的c片段。

#include <stdio.h>      /* printf */
#include <math.h>       /* ceil */

int main ()
{
  printf ( "ceil of 2.3 is %.1f\n", ceil(2.3) );
  printf ( "ceil of 3.8 is %.1f\n", ceil(3.8) );
  printf ( "ceil of -2.3 is %.1f\n", ceil(-2.3) );
  printf ( "ceil of -3.8 is %.1f\n", ceil(-3.8) );
  return 0;
}

答案 3 :(得分:0)

用于舍入到最接近的整数math.h具有nearint

 printf ( "nearbyint (2.3) = %.1f\n", nearbyint(2.3) );
 printf ( "nearbyint (3.8) = %.1f\n", nearbyint(3.8) );

输出:

nearbyint (2.3) = 2.0
nearbyint (3.8) = 4.0

或者如果你想在.5

时打破默认的舍入行为
int totalSum= (total - floor(total) ) >= 0.5 ? ceil(total) : floor(total);

答案 4 :(得分:0)

1)10.75 + 17 * 10.75 / 100 + 5 * 10.75 / 100 = 13.115 ......为什么我得不到12.50?

2)你怎么知道它是12.50,你如何检查结果的价值? (它可能只有12.4999 ...,因此当它被格式化为两位小数时,它将变为12.50)确保检查实际的实际值(理想情况下在调试器或转储内存中以字节为单位并手动重建值) ),而不是一些字符串格式化的中间。

3)这不是一些生产代码,对吗?金额不是用实际财务软件中的双倍计算的,因为双精度不够准确,你会遇到所有类型的难题,包括四舍五入到增值税等。如果这是真的,你就不能胜任这个任务,问一下求助一些专业人士。

答案:

std::round通常应该做你需要的。如果它以12结尾,那么这是因为该值小于12.5。

如果四舍五入到小数点后两位显示为12.50,那么你就会遇到真正财务软件的“各种难题”之一。

然后你应该使用字符串表示创建自己的round,就像这个例子一样(不处理负数并重新发明轮子):

#include <iostream>
#include <string>

/**
 * Rounds floating point value in std::string type.
 * Works only for positive values, and without "+" sign!
 * ie. regexp ~\d*\.?\d*~ formatting.
 * For malformed input the output is undefined (but should not crash).
 **/
std::string financialRound(const std::string & amount) {
    const size_t dotPos = amount.find_first_of('.');
    if (std::string::npos == dotPos) return amount; // no decimals found
    // copy whole part into temporary result
    std::string result = (0 < dotPos) ? amount.substr(0, dotPos) : "0";
    const size_t firstDecimalPos = dotPos + 1;
    // see if there is 5 to 9 digit after dot
    if (amount.size() <= firstDecimalPos) return result; // no char
    const char firstDecimal = amount.at(firstDecimalPos);
    if (firstDecimal < '5' || '9' < firstDecimal) return result; //not 5-9
    // add 1 to the result
    int patchPos = (int)result.size();
    while (0 <= --patchPos) {
        ++result.at(patchPos);
        if ('9'+1 == result.at(patchPos)) result.at(patchPos) = '0';
        else break;
    }
    // check if additional 1 is required (add overflow)
    if (-1 == patchPos) result.insert(result.begin(), '1');
    return result;
}

void tryValue(const std::string & amount) {
    printf("\"%s\" is rounded to \"%s\"\n", amount.c_str(), financialRound(amount).c_str());
}

int main()
{
    printf("Trying normal values...\n");
    tryValue("12.50");
    tryValue("12.49");
    tryValue(".49");
    tryValue(".50");
    tryValue("9.49");
    tryValue("9.50");
    printf("Missing decimals...\n");
    tryValue("12");
    tryValue("12.");
    printf("Malformed...\n");
    tryValue("");
    tryValue("a.4");
    tryValue("a.5");
    tryValue("12..");
}
cpp.sh上的

live demo