代码之家  ›  专栏  ›  技术社区  ›  Piero Borrelli

使用4/5舍入规则舍入数字

  •  4
  • Piero Borrelli  · 技术社区  · 8 年前

    我目前正在学习C++。

    我必须写一个简单的 class Money 它执行涉及美元和美分的计算,其中算术必须使用4/5取整规则精确到最后一美分。

    我以前从未处理过金钱问题,所以我在理解如何从课堂上获得最好的成绩方面遇到了一些困难。我知道我不应该用 float 。所以我使用两个数据成员为我的类分别存储美元和美分:

    long int dollars
    long int cents 
    

    我的问题是,我不知道何时以及如何取整数字。当我试图实现这个类的输入运算符时,我问了自己这个问题。假设用户输入值: 12.456, 45.999, 9.54 .

    1. 我应该什么时候舍入这些数字?

    2. 我应该先在算术运算中使用它们,然后将结果四舍五入,还是在它们输入程序时直接四舍五进?

    4 回复  |  直到 8 年前
        1
  •  3
  •   Clifford    2 年前

    拥有单独的美元和美分成员只会使代码变得更加复杂。只需使用美分,然后重载算术和赋值运算符、构造函数,可能还需要<&书信电报;并且>>用于I/O。

    加法和减法是微不足道的,在这种情况下,只是按100缩放的普通整数运算。通常,定点除法/乘法需要重新缩放;在这种情况下,你可以忽略这一点,因为金钱除以或乘以金钱是没有意义的;但是,您可能希望重载整数和浮点类型的货币乘法或除法(例如,用于税收、折扣或利息计算)。

    通过过载<&书信电报;并且>>对于货币运算符,您可以通过将其转换为/从来控制美分值的输入或显示方式 dollars.cents .

    有许多场景可能需要舍入,但在大多数情况下,可以通过运算符重载来处理。例如,以美元为单位的用户输入可以由赋值运算符和构造函数处理,而利息、税收或股份分配计算可能会导致小数点,可以通过重载*和/运算符来处理(尽管可能在内部使用赋值运算符或构造函数,因此您只需要在一个位置进行舍入)。

    保持以美分为单位的值,并将浮点输入或中间美元值四舍五入为美分,正负值处理可按如下方式实现:

    long long cents = static_cast<long long>((std::abs(dollars_fp) + 0.005) * 100) ;
    if( dollars_fp < 0 )
    {
        cents = -cents ;
    }
    
        2
  •  1
  •   Ziezi sethi    8 年前

    我建议你对 cents 并且仅使用四舍五入来将量打印到标准输出。

    你可以使用 locale 解析货币表达式和 std::stringstream 随着 stream manipulators 以指定精度,作为实现所需类的基结构。

    下面是美分和美元之间的转换示例:

    int sum_in_cents = 10000;
    
    // stringstream imbued with the local configuration
    std::stringstream ss;
    ss.imbue(std::locale(""));
    
    // ss contains $100.00 (assuming a en_US locale configuration)
    ss << std::showbase << std::put_money(sum_in_cents);
    

    此外,还有 a boost library 用于货币格式。


    注:传统的4/5舍入由标准库函数执行 round() 。如果你想自己实现一些东西,你可以做:

    double round (double n) 
    {
        return (n > 0.0) ? floor(n + 0.5) : ceil(n - 0.5);
    }
    

    如果您想要取整的整数结果,则不需要 ceil() floor() :

    int round (double i)
    {
        return (i > 0.0) ? (i + 0.5) : (i - 0.5); 
    }
    

        3
  •  0
  •   Kem Andrew    8 年前
    1. 我能说的最好的方法是将值作为字符串读入。此时,您可以操作每个项目/数字,因为字符串本质上是字符数组。

    2. 另一种选择是键入cast,例如。

      浮动x=10.01;//x=10.01

      (整数)y=x;//y=10

    以浮点形式读取值,并从中对其进行分解。

    希望这有帮助!

        4
  •  0
  •   TheTrueJard    8 年前

    我建议将输入乘以1000左右,使输入成为一个整数,这样您对其进行的操作更准确。四舍五入后,您可以使用整数除法来计算美元,使用余数运算符来计算美分(乘以10)。至于你的第二个问题,在四舍五入之前,你至少应该把数字转换成美元和美分的整数,然后你可以选择你喜欢的那个。以下是舍入输入的示例:

    /* Note: Code untested */
    double x;
    std::cin >> x;    // x = 45.999
    long y = x * 1000;        // y = 45999
    
    int dollars = y / 1000;    // dollars = 45
    int cents = y % 1000       // cents = 999 (divide by 10 to get real # of cents)
    
    if (cents % 10 >= 5) {   // if last digit should be rounded up (true)
        cents += 10;            // add 10 (cents = 1009)
        cents -= (cents % 10);   // remove the last digit (cents = 1000)
    } 
    else if (cents % 10 < 5) {  // if last digit should be rounded down (false)
        cents -= (cents % 10);   // remove last digit
    }
    
    cents /= 10;        // make cents a factor of 100 instead of 1000 (cents = 100)
    
    if (cents >= 100) {    // if cents more than $1 (true)
        dollars++;       // adjust dollars (dollars = 46)
        cents -= 100;     // remove 100 from cents (cents = 0)
    }
    
    // prints "Amount is $46.0"
    std::cout << "Amount is $" << dollars << "." << cents << "\n";
    

    至于类型转换,它们不是四舍五入的最佳选择。如果要使用以下代码:

    double x = 45.999;
    int y = (int)x;
    

    你会得到 y == 45 因为当将任何浮点类型强制转换为任何整数类型时,分数部分将被完全忽略。

    希望这有帮助。