getfloat返回23.7999

Too*_*ool 2 c floating-point

#define MAXBUF 1000
int buf[MAXBUF];
int buffered = 0;
int bufp = 0;

int getch()
{
    if(bufp > 0) {
       if(!--bufp)
          buffered = 0;

       return buf[bufp];
    }
    else {
       buffered = 0;
       return getchar();
    }

}

void ungetch(int c)
{
     buf[bufp++] = c;
     buffered = 1;
}

int getfloat(float *pn)
{
    int c, sign, sawsign;
    float power = 1.0;

    while(isspace(c=getch()))
         ;

    if(!isdigit(c) && c!= '+' && c!= '-' && c != '.') {
          ungetch(c);
          return 0;
    }

    sign = (c == '-') ? -1 : 1;

    if(sawsign = (c == '-' || c == '+'))
       c = getch();

    if(c != '.' && !isdigit(c)) {
         ungetch(c);

         if(sawsign)
            ungetch((sign == -1) ? '-' : '+');

         return 0;
    }

    for(*pn = 0.0; isdigit(c); c = getch())
        *pn = 10.0 * *pn + (float)(c - '0');

    if(c == '.')
       while(isdigit(c = getch())) {
         *pn = 10.0 * *pn + (float)(c - '0');
          power *= 10.0;
       }

    *pn *= sign;
    *pn /= power;

    ungetch(c);
    return c;
}
Run Code Online (Sandbox Code Playgroud)

当我输入23.8时它总是返回23.7999,我不知道为什么.谁能告诉我为什么?

Jaa*_*koK 5

数字以基数2表示,基数2浮点值不能精确地表示每个基数为10的十进制值.您输入的内容23.8将转换为最接近的等效base-2值,该值不完全是23.8.当您打印此近似值时,它将打印为23.7999.

您也在使用float,这是最小的浮点类型,并且只有24位精度(大约7位十进制数).如果切换到double,精度位数会超过两倍float,因此十进制值(例如23.8)与其double表示之间的差异要小得多.这可能会允许打印程序进行四舍五入更好,所以你看到23.8double.但是,变量中的实际值仍不完全是23.8.

作为一般建议,除非您有大量的浮点值(使内存使用成为您主要关心的问题),否则最好double在需要浮点类型时使用.你没有摆脱所有奇怪的行为,但你会看到它少于float.