【问题标题】:Why does using LONG_MAX in this context work, but using FLT_MAX not work?为什么在这种情况下使用 LONG_MAX 有效,但使用 FLT_MAX 无效?
【发布时间】:2014-12-24 14:20:35
【问题描述】:

我有一个在 Windows 8.1 上使用 MS Visual Studio 2012 用 ANSI C 编写的函数,该函数接收一个字符数组 lexeme,其中空间为 20 chars,并检查有效的单精度浮点数。

我的功能:

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 (strlen(lexeme) > ERR_LEN && (temp > LONG_MAX || temp < FLT_MIN)) /* 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 */
}

如此处提供的,该功能按预期工作,但如果我将LONG_MAX 更改为FLT_MAX,它将不再按预期工作。

我测试的输入:

1.999999999999999911111111111111111111111111111111111111111111111111111111111111111

上面应该产生2.000000 的输出,我将它保存在flt_value 中作为float

999999999999999999999999999999999999999999999999999999999999999999999999999999999.0

0.00000000000000000000000000000000000000000000000000000000000000000000000000000000001

以上都应该触发行return aa_table[ES](lexeme);产生错误Token

我的问题很简单:为什么一个有效而另一个无效?

【问题讨论】:

  • 我认为with space for 20 chars 是一个错字,应该是200?您的输入字符串明显大于 20 个字符!另外,我不明白strlen(lexeme) &gt; ERR_LEN的目的。
  • 不,lexeme 是一个 20 char 数组,我很清楚所有输入都比这更长。应该是这样的,所以我说这是我想要的。而ERR_LEN 定义为8。该函数的目的是获取lexeme 并检查一个有效的浮点数。如果它是有效的 FP 编号,那么我将其存储在 Token 属性中并返回 Token。如果它不是有效的浮点数,那么我调用return aa_table[ES](lexeme); 行以返回错误Token
  • 是的,“我很清楚”你的函数的目的,但你怎么能说输入是你显示的字符串,而 lexeme 只有 20 个字符?我没有问ERR_LEN 有什么价值,而是strlen(lexeme) &gt; ERR_LEN 的目的到底是什么。
  • 应该检查以确保找到的有效float 号码是 8 位数字。例如,如果lexeme 包含0.000000,则生成的Token0.000000 输出为float 而不是0.0 作为错误。

标签: c arrays string floating-point


【解决方案1】:

数组中有太多char

lexeme 是一个 20 字符的数组,但它用 999999999999...999999999999.00.000...00000000000000000000001 填充。这会覆盖控制谁知道什么的内存。在任何一种情况下,这都会调用未定义的行为,并且检查其余代码是徒劳的。 OP 报告 1.9999999999999999111111111....11111111 的工作正常,但未验证它是否会再次工作。

确保lexeme 填写的char 不超过19 个(为'\0' 留下1 个char)。

【讨论】:

  • @Benjamin 如果这没有意义,请发布填写lexeme 并调用aa_func08() 的代码。
猜你喜欢
  • 1970-01-01
  • 2018-10-17
  • 1970-01-01
  • 2019-01-19
  • 2022-12-18
  • 2017-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多