如何将char数组转换为float并检查其范围?

时间:2014-10-28 16:48:21

标签: c arrays string floating-point

我正在Microsoft Visual Studio 2012中构建一个应用程序,我有一个函数,它接受一个char数组,并且应该返回一个单精度浮点数。

我的功能:

Token aa_func08(char lexeme[]){
    Token t; /* floating point literal Token to be returned */
    double temp; /* floating point value of character array */

    temp = atof(lexeme); /* convert character array to floating point value */
    if ((FLT_MAX - temp <= FLT_EPSILON) || (temp - FLT_MIN <= FLT_EPSILON)) /* floating point value is outside the accepted range */
        return aa_table[ES](lexeme); /* return an error Token */
    t.code = FPL_T; /* set Token code */
    t.attribute.flt_value = (float)temp; /* set Token integer value to floating point literal value */
    return t; /* return floating point literal Token */
}

我想检查float值与float数据类型的最大值和最小值的比较,我还需要检查char数组的长度。

我期望的输出如下:

如果我传入:

1.999999999999999911111111111111111111111111111111111111111111111111111111111111111

我希望得到:2.000000

如果我传入:

999999999999999999999999999999999999999999999999999999999999999999999999999999999.0

我希望得到:99999999999999999999

如果我传入:

0.00000000000000000000000000000000000000000000000000000000000000000000000000000000001

我希望得到:0.000000000000000000

有人知道我如何才能取得这样的成绩,或者至少指出我正确的方向吗?谢谢!

修改

对于第一种情况,结果2.000000由32位浮点数表示。另外两个结果只是字符串lexeme被截断为前20个字符。总而言之,如果lexeme表示有效float,则表示为浮点数,但如果lexeme表示无效float(超出范围,则会丢失数字)小数点等等)然后lexeme的前20个字符是我返回的(不是实际的float)。

2 个答案:

答案 0 :(得分:1)

您可能想要阅读:What Every Computer Scientist Should Know About Floating-Point Arithmetic

具体来说,你不会得到“99999999999999999999”,或浮点类型的20位精度(甚至是双精度)。第二,取决于您为“0.000000000000000000000000000000000000000000000000000000001”获得1E-83可能获得的值。您可能还想查看IEEE Floading Point

你的例子与你的目标不符,暗示一个或另一个会导致失望。如果需要将字符串转换为32位浮点类型,则需要遵循该格式的限制。如果您需要示例描述的精度(和行为),则可能需要编写某种自定义数字类型。

答案 1 :(得分:0)

看起来OP的目标是通过使用字符串float转换然后测试限制来检查数字是否适合double 范围

极限测试无效。错误使用FLT_EPSILONFLT_MIN

建议只需将double与+/- FLT_MAX进行比较。

volatile double d = atof(lexeme);
if ((d > FLT_MAX) || (d < -FLT_MAX)) {
  return aa_table[ES](lexeme); 
}
t.code = FPL_T; 
t.attribute.flt_value = (float) d;

不清楚OP如何处理NaN。


[编辑]现在看OP还想将输入限制为20 char。建议:

char buf[20+1];
strncpy(buf, lexeme, 20);
buf[20] = '\0';
volatile double d = atof(buf);
...

限制测试仍然有意义,因为输入可能是1.0e100,或超出FLT_MAX