c++ - double 不能正确减去小数

标签 c++ double precision subtraction decimal

我正在编写类似轮盘赌的 C++ 命令行程序。用户可以输入小数值/数字进行投注。我正在使用双类型变量来实现这一点。但是,例如,如果我以 1 美元开始,然后输了 0.23 美元,然后下注 0.55 美元并输了,然后下注 0.07 美元并再次输了,我不能下注 0.15 美元,即使程序声称我实际上有 0.15 美元美元(你不能下注比你有更多的钱)。看来程序不正确地减法。不过,我还是可以下注0.149美元。对于它的值(value),我使用 stringstream 将用户的投注输入转换为 double 类型的值。有人可以解释这里发生了什么吗?

这是我的代码:

#include <iostream>
#include <sstream>
using namespace std; //Std namespace.

void string_to_number(string input, double& destination);

class Roulette {
private:
int randoms;
double money, choice, bet;
string input;
public:
int play = 0;
void start_amount() {
    cout<<"How much money do you have?: ";
    getline(cin, input);
    string_to_number(input, money);
}

void betting() {
   cout<<"How much money would you like to bet?: ";
    getline(cin, input);
    string_to_number(input, bet);

    while (bet > money) {
        cout<<"You can't bet more money than you have ("<<money<<" dollars). Please enter again: ";
        getline(cin, input);
        string_to_number(input, bet);
    }
}

void choose_number() {
    cout<<"Which number do you choose? (0-35): ";
    getline(cin, input);
    string_to_number(input, choice);
}

void random_number() {
    cout<<"The wheel is spinning..."<<endl<<flush;
    randoms = (rand())%36;
}

void scenarios() {
    cout<<"The wheel shows number "<<randoms;
    if (randoms == choice) {
        money += bet;

        cout<<", which means that you win "<<bet<<" dollars! You currently have "<<money<<" dollars."<<flush<<endl;
    }
    else {
        money -= bet;

        cout<<", which means that you lose "<<bet<<" dollars. You currently have "<<money<<" dollars."<<flush<<endl;
    }

}

};

int main(int argc, const char * argv[])
{
srand(unsigned(time(0)));
Roulette a;
a.start_amount();

while (a.play == 0) {
    a.betting();
    a.choose_number();
    a.random_number();
    a.scenarios();
}

return 0;
}


void string_to_number(string input, double& destination) {
stringstream convert(input);
if ( !(convert >> destination) )
    destination = 0;
}

最佳答案

这不是因为程序减法错误 - 这是因为二进制小数和小数不是“完全数学兼容” - 有限小数通常是无限周期性二进制小数。

因此,对于像 0.15 这样的小数,存在几个有效的 double 近似值,作为减法的结果,您得到了其中一个 (A),而作为从字符串“0.15”转换的结果,您得到了另一个 (B)。意外地,B 看起来比 A 大。

您应该使用整数美分,而不是双倍美元以保持精确的十进制 舍入。更通用的解决方案是使用一些十进制数字类(如 this ),它很容易使用整数实现小数运算。

一些十进制(和二进制)数字类实现了 arbitrary precision arithmetic - 它解决了定点部分大于硬件支持的 double 类型的任务。在规定四舍五入到美分(2 位小数)的应用程序中,您不需要它。

关于c++ - double 不能正确减去小数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19407539/

相关文章:

c# - 将空值绑定(bind)到 wpf 控件的宽度和高度时出现绑定(bind)错误

c++ - 混淆 double 和 float 数据类型

c# - C#中的双重比较精度损失,加减 double 时发生精度损失

java - Android 基础数学不及格

c++ - 初始化抛出异常的对象

c++ - 使用 clang++ 和 SDL 包含路径

javascript - node.js 在 Web 开发环境中的位置在哪里?

c++ - 当我尝试调试时,Visual Studio 2008 显示 "the specified file is an unrecognized or unsupported binary format"

c++ - double 的重载比较以允许数值错误

c++ - 当通过 C/C++ 中的 double 传输时,是否保证保留 float ?