问题描述
有没有办法从Windows CRT string
到 float
float
到 string
转换器在C中没有信息丢失( strtod
, sscanf
或 atof
返回原始 float
舍入模式不会改变。
我在MinGW或Visual C ++下,因此这些调用会进入MSVC ++运行时。问题是,我不能得到它来解析任何特殊的值(如Inf
或NaN
)。 Inf
是OK(在解析不适合 float
的值后返回,例如1e999
)。
/ *返回浮点的最短字符串表示形式一个成功的scanf往返。
*保证适合13个字符(包括最后的'\0')。
* /
char * ftoa(char * res,float f){
float r = 0;
int i,j,len,e = floor(log10(f))+ 1;
char fmt [8];
union {float f; int32_t i; } u = {f};
if(f> FLT_MAX){sprintf(res,1e999); return res; }
if(f
if((ui& 0x7F800000)== 0x7F800000){// NaN
sprintf(res,ui == 0x7FC00000?%sNaN:%sNaN%d, ui< 0? - :,ui& 0x7FFFFF);
return res;
}
//计算不带指数的最短字符串(123000,0.15)
if(!f || e> -4&& e& 10){
for(i = 0; i sprintf(fmt,%%。%df,i)
sprintf(res,fmt,f);
sscanf(res,%f,& r); if(r == f)break;
}
}
if(r == f)len = strlen(res);
else len = 1e9;
if(!f)return res; //处理0和-0
//计算具有指数(123e3,15e-2)的最短字符串
for(i = 0; i sprintf(res,%.0fe%d,f * pow(10,-e),e); sscanf(res,%f,& r); if(r == f)break;
j = strlen(res); if(j> = lenF)break;
while(res [j]!='e')j--;
res [j-1] - ; sscanf(res,%f,& r); if(r == f)break; // try + -1
res [j-1] + = 2; sscanf(res,%f,& r);如果(r == f)break;
e--;
}
if(len return res;
}
如果发生溢出,则它们返回HUGE_VAL,如果不能解析输入则返回0,或者发生下溢。
Is there any way to get NaN
s from the Windows CRT string
to float
functions?
Why: I'm writing an IEEE float
to string
converter in C with no information loss (strtod
, sscanf
or atof
return the original float
) provided the rounding mode doesn't change.
I'm under MinGW or Visual C++, so these calls go to the MSVC++ runtime. The problem is that I can't get it to parse any special values (like "Inf"
or "NaN"
). Inf
is OK (it's returned after parsing a value that doesn't fit in a float
, such as "1e999"
).
/* Return the shortest string representation of a float with a successful scanf round-trip.
* Guaranteed to fit in 13 chars (including the final '\0').
*/
char* ftoa(char* res, float f) {
float r = 0;
int i, j, len, e = floor(log10(f)) + 1;
char fmt[8];
union { float f; int32_t i; } u = { f } ;
if (f > FLT_MAX) { sprintf(res, "1e999"); return res; }
if (f < -FLT_MAX) { sprintf(res, "-1e999"); return res; }
if ((u.i & 0x7F800000) == 0x7F800000) { // NaN
sprintf(res, u.i == 0x7FC00000 ? "%sNaN" : "%sNaN%d", u.i<0 ? "-" : "", u.i & 0x7FFFFF);
return res;
}
// compute the shortest string without exponent ("123000", "0.15")
if (!f || e>-4 && e<10) {
for (i=0; i<=10; i++) {
sprintf(fmt, "%%.%df", i);
sprintf(res, fmt, f);
sscanf(res, "%f", &r); if (r==f) break;
}
}
if (r==f) len = strlen(res);
else len = 1e9;
if (!f) return res; // handle 0 and -0
// compute the shortest string with exponent ("123e3", "15e-2")
for (i=0; i<9; i++) {
sprintf(res, "%.0fe%d", f * pow(10,-e), e); sscanf(res, "%f", &r); if (r==f) break;
j = strlen(res); if (j >= lenF) break;
while (res[j] != 'e') j--;
res[j-1]--; sscanf(res, "%f", &r); if (r==f) break; // try +-1
res[j-1]+=2; sscanf(res, "%f", &r); if (r==f) break;
e--;
}
if (len <= strlen(res)) sprintf(res, fmt, f);
return res;
}
No. They return HUGE_VAL if overflow would occur and 0 if the input can't be parsed or underflow occurs.
这篇关于无法从MSVCRT strtod / sscanf / atof函数中获取NaN的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!