我正在尝试将字符串转换为浮点数。我知道已有功能可以做到这一点。我只是为了练习这样做。我的功能适用于简单的数字,如123.123,1234,-678.8。但是当我尝试将字符串.99999999转换为浮点数时,我最终得到1.这显然是一个问题。我不知道这是因为.99999999不能用浮点数表示,或者我做错了什么。我问的问题是如何计算浮点数可以表达的最大分数。由于缺乏更好的术语,我如何知道浮子即将溢出?
这是我到目前为止所拥有的。
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
int cstrtof(const char *cstr, float *f);
int cstrtof(const char *cstr, float *f)
{
unsigned short int i = 0;
unsigned short int bool_fraction = 0;
float tmp_f = 0;
if(cstr[0] == '\000') return -1;
else if(cstr[0] == '-') i = 1;
for(; cstr[i] != '\000'; i++)
{
printf("tmp_f = %f\n", tmp_f);
if(cstr[i] >= '0' && cstr[i] <= '9')
{
if(tmp_f > (FLT_MAX - (cstr[i] - '0')) / 10) return -2;
else tmp_f = tmp_f * 10 + (cstr[i] - '0');
}
else if(cstr[i] == '.') bool_fraction = i+1;
else return i+1;
}
printf("tmp_f = %f\nbool_fraction = %i\n", tmp_f, bool_fraction);
if(bool_fraction)
{
for(bool_fraction--; bool_fraction < i-1; bool_fraction++, tmp_f /= 10)
{
printf("tmp_f = %f\n", tmp_f);
}
}
printf("tmp_f = %f\nbool_fraction = %i\n", tmp_f, bool_fraction);
if(cstr[0] == '-') *f = tmp_f*-1;
else *f = tmp_f;
return 0;
}
int main(int argc, char *argv[])
{
float f = 0;
int return_value = 0;
return_value = cstrtof(argv[1], &f);
if(return_value == 0)
{
printf("f = %.11f\n", f);
}
else if(return_value == -1)
{
printf("ERROR Empty String\n");
}
else if(return_value == -2)
{
printf("ERROR Data Type Overflow\n");
}
else
{
printf("ERROR Invalid character '%c'\n", argv[1][return_value-1]);
}
return 0;
}
cstrtof()也基于以下功能。
int cstrtoslli(const char *cstr, signed long long int *slli)
{
unsigned short int i = 0;
signed long long int tmp_slli = 0;
if(cstr[0] == '\000') return -1;
else if(cstr[0] == '-') i = 1;
else if(cstr[0] == '0') return -2;
for(; cstr[i] != '\000'; i++)
{
if(cstr[i] >= '0' && cstr[i] <= '9')
{
//LLONG_MAX is defined in limits.h
if(tmp_slli > (LLONG_MAX - (cstr[i] - '0')) / 10) return -3;
else tmp_slli = tmp_slli * 10 + (cstr[i] - '0');
}
else return i+1;
}
if(cstr[0] == '-') *slli = tmp_slli*-1;
else *slli = tmp_slli;
return 0;
}
答案 0 :(得分:2)
float
返回小于1的最大可表示nexttowardf(1, -INFINITY)
值。
这通常具有不同的分数部分,例如,小于2的最大可表示float
值,即nexttowardf(2, -INFINITY)
。这是因为不同大小的数量通常具有可用于分数部分的不同比特数(因为一些比特用于整数部分)。小数部分的大数字为零位。
当float
是IEEE-754 32位二进制浮点值(在现代实现中很常见)时,1以下的最大float
为0.999999940395355224609375。当将十进制数字转换为float
的例程质量良好且舍入模式为最接近(常见默认值)时,则数字从舍入切换到0.999999940395355224609375以舍入为1的点位于这两个值之间(确切的中点将舍入为1)。
将十进制数字正确转换为二进制浮点很复杂。这是一个已经解决的问题,并且有关于它的学术论文,但是如果它正确地完成了工作,你通常应该依赖现有的库代码。正确地做好自己需要花费大量时间。
答案 1 :(得分:1)
我问的问题是如何计算浮点数可以表达的最大分数。由于缺乏更好的术语,我如何知道浮子即将溢出?
您正在寻找:
#include <math.h>
… nextafterf(1.0f, 0.0f) …
但是你应该熟悉C99浮点数的十六进制表示法,然后你可以直接写出常量:0x1.fffffep-1
。