Получение странных чисел, возвращаемых функцией в C

У меня есть пара файлов:

оценка_sin.c:

int evaluate_sin(int deg) {
    double j = deg_to_rad(deg);
    j = sin(j);
    printf("sin(%d) =  %d\n", deg, j);
    return j;
}

deg_to_rad.c

double deg_to_rad(int deg) {
    double rad = (3.14 * deg) / 180;
    return rad;
}

Когда я передаю переменную "deg" (которая является целым числом) в моей функции Assessment_sin в deg_to_rad j, это заканчивается как некоторое случайное число, например -90503293. Почему это?


c
person ahota    schedule 06.03.2013    source источник
comment
Почти уверен, что double и int (%d) не имеют одинакового битового формата для этой печати. Попробуйте %f   -  person WhozCraig    schedule 06.03.2013
comment
Можете ли вы использовать %f вместо этого?   -  person alex    schedule 06.03.2013
comment
Можете ли вы также опубликовать вызов функции? Так что хотя бы мы можем видеть параметры.   -  person Shashank Kadne    schedule 06.03.2013
comment
разве это не должно быть %lf ?? @WhozCraig :-P   -  person Aniket Inge    schedule 06.03.2013
comment
Откуда люди взяли идею, что они могут научиться программировать, не научившись читать руководство? Ну и мануал или комментарии stackoverflow, которые воспроизводят мануал :(   -  person autistic    schedule 06.03.2013
comment
@Aniket Черт, я не знаю. Я никогда не использую числа с плавающей запятой в своей повседневной жизни, а тем более не печатаю. Я просто знал, что это не было %d =P. Судя по диаграмме, я не думаю, что это имеет значение, но, вероятно, лучшая форма, как у вас есть.   -  person WhozCraig    schedule 06.03.2013


Ответы (3)


Обратите внимание, что j является двойным, а не целым числом

Так что printf("sin(%d) = %d\n", deg, j); нужно поставить с printf("sin(%d) = %f\n", deg, j);

person Community    schedule 06.03.2013

Вы не объявили deg_to_rad():

extern double deg_to_rad(int deg);

прежде чем использовать его. Ваш код предполагает, что он возвращает int и преобразует его в double.

У вас должен быть заголовок degtorad.h.

degtorad.h

#ifndef DEGTORAD_H_INCLUDED
#define DEGTORAD_H_INCLUDED

extern double deg_to_rad(int deg);

#endif /* DEGTORAD_H_INCLUDED */

(В этом примере защита заголовка не является обязательной на 100%, но это хорошая основа для более сложных случаев, когда защита заголовка необходима.)

Тогда ваши программные файлы включают этот заголовок. Где-то вдоль линии вам также нужно объявить evaluate_sin(); он может войти в тот же заголовок.

оценка_sin.c:

#include <math.h>
#include <stdio.h>
#include "degtorad.h"

double evaluate_sin(int deg)
{
    double j = deg_to_rad(deg);
    j = sin(j);
    printf("sin(%d) =  %.6f\n", deg, j);
    return j;
}

Обратите также внимание на изменение типа возвращаемого значения (double вместо int); он вернет 0, если вам не удастся передать точное нечетное число, кратное π/2 (когда он вернет -1 или +1). А также изменение формата значения double (%.6f вместо %d, которое выводило бы целое число).

Если вы используете GCC, вам нужно включить предупреждения компиляции; не менее -Wall.

deg_to_rad.c

#include "deg_to_rad.h"

double deg_to_rad(int deg)
{
    double rad = (3.14 * deg) / 180;
    return rad;
}
person Jonathan Leffler    schedule 06.03.2013

хотя printf("%f", doubleValue) подходит для двойников, я бы все же посоветовал сделать его максимально простым и использовать способ, которым scanf() требует %lf для двойников. Это придает программе ощущение согласованности.

так что да, я бы предложил:

printf("sin(%d) = %lf\n", deg, j);

person Aniket Inge    schedule 06.03.2013
comment
Это нормально, если вы уверены, что у вас есть компилятор C99. Использование %lf с C89 вызывает неопределенное поведение, что никогда не является хорошей идеей. И, конечно же, главный компилятор, «застрявший во времени», — это компилятор Microsoft C, который является компилятором C89 с очень небольшим количеством улучшений C99. Возможно, MSDN определяет поведение %lf для MSVC, но будьте осторожны. - person Jonathan Leffler; 06.03.2013