在 C(不是 C++)中,我将使用 strtod/strol 和 <limits.h> 和 <float.h> 中的最大值的组合:
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <float.h>
/* Now, we know the following values:
INT_MAX, INT_MIN, SHRT_MAX, SHRT_MIN, CHAR_MAX, CHAR_MIN, etc. */
typedef union tagMyUnion
{
char TChar_ ; short TShort_ ; long TLong_ ; double TDouble_ ;
} MyUnion ;
typedef enum tagMyEnum
{
TChar, TShort, TLong, TDouble, TNaN
} MyEnum ;
void whatIsTheValue(const char * string_, MyEnum * enum_, MyUnion * union_)
{
char * endptr ;
long lValue ;
double dValue ;
*enum_ = TNaN ;
/* integer value */
lValue = strtol(string_, &endptr, 10) ;
if(*endptr == 0) /* It is an integer value ! */
{
if((lValue >= CHAR_MIN) && (lValue <= CHAR_MAX)) /* is it a char ? */
{
*enum_ = TChar ;
union_->TChar_ = (char) lValue ;
}
else if((lValue >= SHRT_MIN) && (lValue <= SHRT_MAX)) /* is it a short ? */
{
*enum_ = TShort ;
union_->TShort_ = (short) lValue ;
}
else if((lValue >= LONG_MIN) && (lValue <= LONG_MAX)) /* is it a long ? */
{
*enum_ = TLong ;
union_->TLong_ = (long) lValue ;
}
return ;
}
/* real value */
dValue = strtod(string_, &endptr) ;
if(*endptr == 0) /* It is an real value ! */
{
if((dValue >= -DBL_MAX) && (dValue <= DBL_MAX)) /* is it a double ? */
{
*enum_ = TDouble ;
union_->TDouble_ = (double) dValue ;
}
return ;
}
return ;
}
void studyValue(const char * string_)
{
MyEnum enum_ ;
MyUnion union_ ;
whatIsTheValue(string_, &enum_, &union_) ;
switch(enum_)
{
case TChar : printf("It is a char : %li\n", (long) union_.TChar_) ; break ;
case TShort : printf("It is a short : %li\n", (long) union_.TShort_) ; break ;
case TLong : printf("It is a long : %li\n", (long) union_.TLong_) ; break ;
case TDouble : printf("It is a double : %f\n", (double) union_.TDouble_) ; break ;
case TNaN : printf("It is a not a number : %s\n", string_) ; break ;
default : printf("I really don't know : %s\n", string_) ; break ;
}
}
int main(int argc, char **argv)
{
studyValue("25") ;
studyValue("-25") ;
studyValue("30000") ;
studyValue("-30000") ;
studyValue("300000") ;
studyValue("-300000") ;
studyValue("25.5") ;
studyValue("-25.5") ;
studyValue("25555555.55555555") ;
studyValue("-25555555.55555555") ;
studyValue("Hello World") ;
studyValue("555-55-55") ;
return 0;
}
结果如下:
[25] is a char : 25
[-25] is a char : -25
[30000] is a short : 30000
[-30000] is a short : -30000
[300000] is a long : 300000
[-300000] is a long : -300000
[25.5] is a double : 25.500000
[-25.5] is a double : -25.500000
[25555555.55555555] is a double : 25555555.555556
[-25555555.55555555] is a double : -25555555.555556
[Hello World] is a not a number
[555-55-55] is a not a number
对不起我生锈的C。
:-)
因此,实质上,您在调用 whatIsTheValue 之后,通过 MyEnum 枚举检索类型,然后根据此枚举中的值,从联合 MyUnion 检索正确的值,正确键入。
请注意,查找数字是双精度数还是浮点数有点复杂,因为差异似乎在于精度,即您的数字可以用双精度数还是浮点数表示。大多数“十进制实数”数字不能完全表示为双精度数,我不会打扰。
还要注意,有一个问题,因为 25.0 既可以是实数,也可以是整数。我比较“dValue == (double)(long)dValue”,我想你应该知道是否是一个整数,再一次,没有考虑到计算机使用的二进制实数通常会出现的精度问题。