我正在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
)。
答案 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_EPSILON
和FLT_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
。