0
  • Platform: Linux 3.2.0 (Debian 7.0)
  • Compiler: GCC 4.7.2 (Debian 4.7.2-5)

I am trying to convert character strings into floats. I am aware that there are already functions that do this. I am only doing this for practice. My function works well with simple numbers like 123.123, 1234, -678.8. But when I try to convert the string .99999999 into a float I end up with 1. Which is obviously a problem. I do not know if this is because .99999999 cannot be expressed by a float or if I am doing something incorrectly. The question I am asking is how can I calculate the maximum fraction that a float can express. How do I, for lack of a better term, know when a float is about to overflow?

Here is what I have so far.

#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;
}

Also cstrtof() is based on the following function.

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;
}
4

2 回答 2

2

float小于 1的最大可表示值由 返回nexttowardf(1, -INFINITY)

这通常具有与例如float小于 2 的最大可表示值(即 )不同的小数部分nexttowardf(2, -INFINITY)。这是因为不同大小的数字通常具有不同数量的可用于小数部分的位数(因为一些位用于整数部分)。大数的小数部分为零。

什么时候float是 IEEE-754 32 位二进制浮点值,这在现代实现中很常见,float低于 1 的最大值是 0.999999940395355224609375。当将十进制数字转换float为质量好的例程并且舍入模式是最接近的(常见的默认值)时,数字从舍入到 0.999999940395355224609375 到舍入到 1 的点是这两个值之间的中间值(以及确切的中点将四舍五入为 1)。

将十进制数字正确转换为二进制浮点是复杂的。这是一个已解决的问题,并且有关于它的学术论文,但您通常应该依赖现有的库代码,如果它能够正常工作。自己正确地做这件事需要大量的时间投资。

于 2013-07-27T23:31:18.407 回答
1

我要问的问题是如何计算浮点数可以表达的最大分数。由于缺乏更好的术语,我如何知道浮点数何时即将溢出?

您正在寻找:

#include <math.h>
… nextafterf(1.0f, 0.0f) …

但是你应该熟悉 C99 的浮点数的十六进制表示法,然后你可以直接写常量 : 0x1.fffffep-1

于 2013-07-27T23:31:28.143 回答