C++ 超奇C++;int和float中的黑洞

C++ 超奇C++;int和float中的黑洞,c++,floating-point,int,rounding,C++,Floating Point,Int,Rounding,基本上,我试图在控制台中输入一个值,并将小数点作为一个整数输出,这就是基本上需要发生的事情 我已经开发了一种方法来实现这一点,使用float、int和简单的数学。 我对C++仍然是新的,但是这个错误没有意义。 如果输入0.01、0.02、0.03、0.04、0.06或0.08,则输出错误。 我基本上想把它简化为0.06*100=6 我很确定这是一个简单的错误,但为什么会这样,显然我输入了一个完整的浮点数 #include <iostream> using namespace std;

基本上,我试图在控制台中输入一个值,并将小数点作为一个整数输出,这就是基本上需要发生的事情

我已经开发了一种方法来实现这一点,使用float、int和简单的数学。 我对C++仍然是新的,但是这个错误没有意义。 如果输入0.01、0.02、0.03、0.04、0.06或0.08,则输出错误。 我基本上想把它简化为0.06*100=6

我很确定这是一个简单的错误,但为什么会这样,显然我输入了一个完整的浮点数

#include <iostream>
using namespace std;

int main()
{
    float input = 0;

    while (input <= 0 || input > 999.99)
    {
        cout << "Please enter a number with decimal: ";
        cin >> input;
    }

    int whole_num = input;
    float to_decimal = input - whole_num;
    int decimal = to_decimal * 100;

    cout << decimal << endl;

    return 0;
}

这是因为浮点数不能准确地表示十进制数

计算机使用的浮点数格式是二进制的。这意味着它可以精确地表示1/2、1/4、1/8、1/16……及其组合。所以,你可以说是0.5,或0.25,甚至是0.75(0.5+0.25),这些都是精确的浮点值。但是,不能使用这些分数的组合创建0.01;因此,其值是近似值。与您测试的其他数字类似


这是使用二进制浮点的固有限制。这不是“超级奇怪”;这是……)

这是因为浮点数不能准确地表示十进制数

计算机使用的浮点数格式是二进制的。这意味着它可以精确地表示1/2、1/4、1/8、1/16……及其组合。所以,你可以说是0.5,或0.25,甚至是0.75(0.5+0.25),这些都是精确的浮点值。但是,不能使用这些分数的组合创建0.01;因此,其值是近似值。与您测试的其他数字类似


这是使用二进制浮点的固有限制。这不是“超级奇怪”;这是……)

我想补充Chris的回答,这是科学计算中一个典型的错误来源。由于实数无法精确表示(计算机中的精度是有限的),因此在计算过程中会累积舍入误差。这是一个非常严重的问题,当你计算长时间的轨道,例如卫星

因此,存在静态分析工具(如),可以帮助您检测此类问题何时会导致代码中出现问题,或确保您的安全

总而言之,这不是“非常奇怪”,但肯定是“非常不幸”


在您的特殊情况下,可能使用
double
而不是
float
会有所帮助,这将提高数字二进制表示的精度。

我要补充Chris的回答,这是科学计算中的一个典型错误源。由于实数无法精确表示(计算机中的精度是有限的),因此在计算过程中会累积舍入误差。这是一个非常严重的问题,当你计算长时间的轨道,例如卫星

因此,存在静态分析工具(如),可以帮助您检测此类问题何时会导致代码中出现问题,或确保您的安全

总而言之,这不是“非常奇怪”,但肯定是“非常不幸”


在您的特定情况下,使用
double
而不是
float
可能会有所帮助,它将提高数字的二进制表示精度。

我只想提醒您,当您将
浮点
结果存储到
int
第行
int decimal=to_decimal*100
如果您将其声明为
float decimal=to_decimal*100
,那么它应该适用于您。

我只想提醒您,当您将
float
结果存储到
int
第行
int decimal=to_decimal*100如果声明为“代码>浮点十进制= ToDeMald** 100代码/代码>,那么它应该为您工作。

< P>正如其他人所提到的,问题是C++中的浮点数符合不幸地不能准确地表示普通数字如0.01、0.03等的情况(您可以用一个简单的循环来验证,如<代码>)。(浮点数F=0;F<P>如其他所提到的,问题是C++中的浮点数符合不幸的不能精确地表示普通数,如0.01、0.03等)(可以用一个简单的循环来检验,如<代码> >(浮点f=0;f),你需要决定你感兴趣的有多少个位。(看起来像2),完成后,这是你能做的最好的了

const int significantBits = 2;
int decimal = (int)(pow(10, significantBits) * div(input, 1.0));

您需要确定您感兴趣的有效位数(看起来像2),完成后,这是您能做的最好的事情:

const int significantBits = 2;
int decimal = (int)(pow(10, significantBits) * div(input, 1.0));

浮点精度的固有问题通过C和C++中的缺省截断圆来放大,例如舍入0.999999到0,可以通过舍入来使事物更加健壮,而不是截断:

int decimal = 0.5f + to_decimal * 100;

你也可以使用一个小值,比如1E-6而不是0.5来获得更强大的截断。这取决于你的具体情况。

< P>浮点精度的固有问题通过C和C++中的默认截断圆来放大,例如,0.999999到0。/p>
int decimal = 0.5f + to_decimal * 100;

您也可以使用较小的值,如1e-6,而不是0.5,以获得更稳健的截断。这取决于您的具体情况。

请阅读。这是每个程序员在进行浮点运算时应该知道的。

请阅读。这是每个程序员在进行浮点运算时应该知道的。

您能提供答案吗放置你得到的?你能提供你得到的输出吗?那太可惜了…你认为有办法实现我想要的吗?好吧,你可以使用十进制浮点库。我相信MPFR,例如,提供了十进制浮点类型。(浮点类型默认为二进制,如果它没有指定为decim。)