Помогите с функцией gcvt в C? - PullRequest
       4

Помогите с функцией gcvt в C?

0 голосов
/ 22 октября 2010
void main()
{
    char buffer[40];
    float x=1.2f,y=.2f;
    printf("%f",(x/y));
    printf( "\n%s\n", gcvt( x/y, 30, buffer ) );        
}

Второй printf дает результат как 6.0000001490116102. Я ожидал, что ответ будет 6.0000 ... полные нули.

Ответы [ 2 ]

1 голос
/ 22 октября 2010

Как и в всех вопросах с плавающей запятой, некоторые числа не могут быть представлены точно.Привыкайте к этому, это факт жизни: -)

С 32-битным значением с плавающей точкой (например), существует около четырех миллиардов чисел, которые могут быть точно представлены.К сожалению, в математике, даже между 0 и 0.00000000000000000000001, есть, хм ..., позвольте мне думать, бесконечное число чисел.

Одна вещь, которую вы может найти полезным использование двойных вместо плавающих - в них больше битов, поэтому они могут представлять более точные числа.Кроме того, есть библиотеки произвольной точности, которые вы можете использовать, если хотите еще большей точности.

Если вы измените свой код на (включая приличную main):

int main (void) {
    char buffer[40];
    float x=1.2f,y=.2f;
    double xd=1.2,yd=.2;

    printf("%f\n",(x/y));
    printf("%.30f\n",(x/y));
    printf( "%s\n\n", gcvt( x/y, 30, buffer ) );

    printf("%f\n",(xd/yd));
    printf("%.30f\n",(xd/yd));
    printf( "%s\n", gcvt( xd/yd, 30, buffer ) );
}

you 'Вы увидите это в действии:

6.000000
6.000000149011610162119723099750
6.00000014901161016211972309975

6.000000
5.999999999999999111821580299875
5.99999999999999911182158029987

Вы можете видеть, что двойники намного ближе к желаемому значению, но они все еще не точны.Двойные значения IEEE754 имеют точность около 16 цифр (с плавающей точкой одинарной точности около 7).

0 голосов
/ 22 октября 2010

Как предполагает paxdiabolo, взгляните на вычисления с плавающей запятой, чтобы узнать, что происходит. Кроме того, моя man страница содержит важный совет:

Эта функция помечена как LEGACY в POSIX.1-2001. POSIX.1-2008 удаляет спецификация gcvt (), рекомендует использовать sprintf (3) вместо этого (хотя snprintf (3) может быть предпочтительнее).

Так что просто не используйте его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...