Целочисленное преобразование в удвоение в C с получением нулевых значений - PullRequest
0 голосов
/ 03 апреля 2011

У меня изначально была функция, которая использует pow (), и я заметил, что она каждый раз возвращает нулевые значения.Во время отладки я обнаружил, что это, кажется, источник проблемы:

#include <math.h>
#include <stdio.h>
#include <string.h>
int foo(int n)
{
        printf("%d is number passed in \n", n);
        double base = (double) n;
        printf("%d is base \n", base);
        printf("%d is power\n", pow(base ,2));

        return (1/2 *( pow( (double) n, 2)));

}

Если я вызову foo для любое целочисленное значение (скажем, 8), второй оператор printfпечатает ноль каждый раз.(И, конечно, третий тоже).Разве преобразование double в int не должно быть простым?

Ответы [ 4 ]

8 голосов
/ 03 апреля 2011

Вы ошиблись в нескольких вещах.

Прежде всего, вы используете спецификатор %d в printf, но вы передаете ему значение double; для double s следует использовать %f 1 , в противном случае printf попытается интерпретировать байты double как int, что приведет к неожиданным результатам (в вашем случае 0).

Обратите внимание, что подобные ошибки обычно замечаются в последних компиляторах с достаточно высоким уровнем предупреждения.

Более того, в ответном заявлении вы написали

1/2 *( pow( (double) n, 2))

Это выражение всегда будет давать ноль из-за фактора 1/2. И 1, и 2 являются int с, таким образом, выполняется целочисленное деление, и, очевидно, это приводит к 0, что убивает все выражение.

Решение: измените 1/2 на 1/2. (где 2. обозначает 2 как double значение, которое переводит операцию в деление с плавающей запятой), или просто замените его на 0.5, или (еще проще) выполнить деление на два в конце выражения.

<ч />
  1. Общая информация: у меня всегда было сомнение, что %f было для float, а что-то еще использовалось для double с; вместо этого оказывается, что для float s не существует спецификатора, поскольку они автоматически преобразуются в double s при передаче в функцию в качестве «переменных аргументов» (поэтому это относится к printf).
0 голосов
/ 03 апреля 2011

чтобы вывести double в c через printf, вы должны использовать% g или% lf (lf означает «long float», который является двойным, фактически float означает одинарную точность: D) % g урезать до наименее значимого числа,% lf - нет. Вы даже можете использовать что-то вроде % .20g, поэтому вы просите написать число с десятичным числом после запятой (или запятой).

Если вы хотите получить результат с плавающей запятой от вашей функции, вы должны изменить объявление функции на

double foo(int n)

Предлагаю изменить обратную строку на эту

return (0.5 * pow( (double) n, 2)));

0,5 - правильный способ написать 1/2 в плавающей запятой.

Но если вам нужно только целое число, то вам следует сделать следующее:

return ((int)pow( (double) n, 2)/2);

На самом деле Pow возвращает двойное число, и вы должны привести его к целому числу

Надеюсь, это полезно :)

0 голосов
/ 03 апреля 2011
    printf("%g is base \n", base);
    printf("%g is power\n", pow(base ,2));

Ваша вторая проблема в том, что вы делаете это:

    return (1/2 *( pow( (double) n, 2)));

Но вы определили, что ваша функция возвращает int. Вам нужно определить, чтобы он возвращал double и не использовать там целочисленную математику:)

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