0

我实现了一个函数StringToDouble将字符串转换为double,但是当我用相同的字符串测试我的函数和标准strtod函数时,结果不同,我不知道为什么会发生这种情况,是不是用double做算术时精度有问题?以及如何修复我的函数,使其生成与 strtod 相同的结果?谢谢。这是我实现的 StringToDouble

    bool StringToDouble(const char *p, double &num) {
    int frac;
    double sign, value, scale;
    bool canConvert = false;
    if (p == NULL || *p == 0) {
        num = 0;
        return false;
    }
    // Skip leading white space, if any.
    while (white_space(*p)) {
        p += 1;
    }

    // Get sign, if any.
    sign = 1.0;
    if (*p == '-') {
        sign = -1.0;
        p += 1;
    } else if (*p == '+') {
        p += 1;
    }
    if (valid_digit(*p)) canConvert = true;
    // Get digits before decimal point or exponent, if any.
    for (value = 0.0; valid_digit(*p); p += 1) {
        value = value * 10.0 + (*p - '0');
    }
   
    // Get digits after decimal point, if any.
    if (*p == '.') {
        double pow10 = 10.0;
        p += 1;
        if (valid_digit(*p)) canConvert = true;
        while (valid_digit(*p)) {
            value += (*p - '0') / pow10;
            pow10 *= 10.0;
            p += 1;
          
        }
    }

    // Handle exponent, if any.
    frac = 0;
    scale = 1.0;
    if ((*p == 'e') || (*p == 'E')) {
        unsigned int expon;

        // Get sign of exponent, if any.
        p += 1;
        if (*p == '-') {
            frac = 1;
            p += 1;
        } else if (*p == '+') {
            p += 1;
        }

        // Get digits of exponent, if any.
        for (expon = 0; valid_digit(*p); p += 1) {
            expon = expon * 10 + (*p - '0');
        }
        if (expon > 308) expon = 308;

        // Calculate scaling factor.

        while (expon >= 50) {
            scale *= 1E50;
            expon -= 50;
        }
        while (expon >= 8) {
            scale *= 1E8;
            expon -= 8;
        }
        while (expon > 0) {
            scale *= 10.0;
            expon -= 1;
        }
    }

    // Return signed and scaled floating point result.
    if (!canConvert) {
        num = 0;
        return false;
    } else {
        num = sign * (frac ? (value / scale) : (value * scale));
        return true;
    }
}

这是我用于测试的代码

const char *p = "3e+100";
double d;
StringToDouble(p, d);
double dd = strtod(p, nullptr);
if (d == dd) {
    cout.precision(17);
    cout << dd << endl
         << d;
} else {
    cout.precision(17);
    cout << "not equal\n";
    cout << dd << endl
         << d;
}

输出是

not equal
2.9999999999999999e+100
3.0000000000000006e+100

我还测试了其他字符串,有些用strtod得到相同的结果,有些不是,所有带指数的情况都得到不同的结果。

4

0 回答 0