c-最大浮点数


  • 平台:Linux 3.2.0(Debian 7.0)
  • 编译器:GCC 4.7.2(Debian 4.7.2-5)

我正在尝试将字符串转换为浮点值。我知道已经有一些功能可以做到这一点。我这样做只是为了练习。我的函数适用于123.123、1234、-678.8等简单数字。但当我尝试将字符串.999999999转换为浮点值时,我得到的结果是1。这显然是个问题。我不知道这是因为.999999999不能用浮点表示,还是我做了一些错误的事情。我要问的问题是如何计算浮点运算所能表达的最大分数。由于没有更好的术语,我如何知道浮点运算何时会溢出?

这是我迄今为止所拥有的。

#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] == '00') return -1;
else if(cstr[0] == '-') i = 1;
for(; cstr[i] != '00'; i++)
{
    printf("tmp_f = %fn", 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 = %fnbool_fraction = %in", tmp_f, bool_fraction);
if(bool_fraction)
{
    for(bool_fraction--; bool_fraction < i-1;  bool_fraction++, tmp_f /= 10)
    {
        printf("tmp_f = %fn", tmp_f);
    }
}
printf("tmp_f = %fnbool_fraction = %in", 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 = %.11fn", f);
}
else if(return_value == -1)
{
    printf("ERROR Empty Stringn");
}
else if(return_value == -2)
{
    printf("ERROR Data Type Overflown");
}
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] == '00') return -1;
else if(cstr[0] == '-') i = 1;
else if(cstr[0] == '0') return -2;
for(; cstr[i] != '00'; 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;
}

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

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

float是现代实现中常见的IEEE-754 32位二进制浮点值时,1以下的最大float为0.999999940395355224609375。当将十进制数字转换为float的例程质量良好,并且取整模式为最接近(常见默认值)时,则数字从取整到0.999999940395355224609375到取整到1的点位于这两个值之间的中点(确切的中点将取整为1)。

正确地将十进制数字转换为二进制浮点是很复杂的。这是一个已经解决的问题,也有关于它的学术论文,但如果它做得好的话,你通常应该依赖现有的库代码。自己做正确的事情需要大量的时间投入。

我要问的问题是如何计算浮点运算所能表达的最大分数。由于没有更好的术语,我如何知道浮点运算何时会溢出?

您正在寻找:

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

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

最新更新