1 Востаннє редагувалося Lata (09.12.2020 17:42:47)

Тема: Функція мовою С, арксинуси

Добрий вечір!
Вивчаю підпрограми-функції мовою С.
Спробувала розв'язати задачу. Даю скріншот з умовою.
Це текст програми:

#include <stdio.h>
#include <math.h>
float arcsinus(float);
int main()
{
    float z, y, Q, k; 
    printf("Уведіть Z\t");
    scanf("%f", &z);
    printf("\nУведіть Y\t");
    scanf("%f", &y);
    if((z>1||z<-1)&&(y>1)||(y<-1))
      printf("\nУведіть інші значення");
      else if(((z>-1)&&(z<1))&&((y>-1)&&(y<1)))
          Q=(2+arcsinus(z))/(5-fabs(arcsinus(y)*arcsinus(y)-arcsinus(z)));
          printf("\nQ=%f",Q);
    return 0;
}
float arcsinus(float X){
    for(float n=1;n<12;n++)
      X+=X+(2*n-1)*pow(X,(2*n+1))/(2*n*(2*n+1));
return X;
}

Працює, але досить дивно.
Наприклад при z=0.2

Уведіть Z       0.2                                                                                                           
                                                                                                                              
Уведіть Y                                                                                                                     
Q=0.400000

. Не розумію, чому не зчитується у.
При z=3, y=4,

Уведіть Z       3                                                                                                             
                                                                                                                              
Уведіть Y       4                                                                                                             
                                                                                                                              
Уведіть інші значення                                                                                                         
Q=0.000000  

. Не розумію, чому тут обчислюється Q.
А ще бував результат Q=-nan або Q=nan.
Що не так з кодом і як це виправити?
Чекаю відповіді і дякую наперед :-*

Post's attachments

Умова.png 106.67 kb, 41 downloads since 2020-12-09 

2 Востаннє редагувалося koala (09.12.2020 17:51:55)

Re: Функція мовою С, арксинуси

Я вам уже казав - бо ви відступи неакуратно робите. Рядок

          printf("\nQ=%f",Q);

знаходиться поза конструкцією if-else, але ви його так написали, ніби всередині, а тепер самі плутаєтеся. У вашому IDE з імовірністю 90% є кнопка "вирівняти код".

І так, ви формулу арксинуса неправильно написали. Вам суму треба шукати, а ви параметр змінюєте.

Подякували: Lata1

3

Re: Функція мовою С, арксинуси

#include <stdio.h>
#include <math.h>
float arcsinus(float);
int main()
{
    float z, y, Q, k; 
    printf("Уведіть Z\t");
    scanf("%f", &z);
    printf("\nУведіть Y\t");
    scanf("%f", &y);
    if((z>1||z<-1)&&(y>1)||(y<-1))
      printf("\nУведіть інші значення");
      else if(((z>-1)&&(z<1))&&((y>-1)&&(y<1)))
          Q=(2+arcsinus(z))/(5-fabs(arcsinus(y)*arcsinus(y)-arcsinus(z)));
printf("\nQ=%f",Q);
    return 0;
}
float arcsinus(float X){
    for(float n=1;n<12;n++)
      X+=X+(2*n-1)*pow(X,(2*n+1))/(2*n*(2*n+1));
return X;
}

тепер спробувала зробити відступи акуратно. Q=nan. Залишається лише подумати над тією формулою.

4

Re: Функція мовою С, арксинуси

Ні, які би відступи я не робила результат - той самий.

5

Re: Функція мовою С, арксинуси

Lata написав:
#include <stdio.h>
#include <math.h>
float arcsinus(float);
int main()
{
    float z, y, Q, k;
    printf("Уведіть Z\t");
    scanf("%f", &z);
    printf("\nУведіть Y\t");
    scanf("%f", &y);
    if ((z > 1 || z < -1) && (y > 1) || (y < -1))
        printf("\nУведіть інші значення");
    else if (((z > -1) && (z < 1)) && ((y > -1) && (y < 1)))
        Q = (2 + arcsinus(z)) / (5 - fabs(arcsinus(y) * arcsinus(y) - arcsinus(z)));
    printf("\nQ=%f", Q);
    return 0;
}
float arcsinus(float X)
{
    for (float n = 1; n < 12; n++)
        X += X + (2 * n - 1) * pow(X, (2 * n + 1)) / (2 * n * (2 * n + 1));
    return X;
}

можете не дякувати

Подякували: Lata, koala2

6

Re: Функція мовою С, арксинуси

Дякую, але знову щось не те :P

7 Востаннє редагувалося Lata (09.12.2020 18:47:43)

Re: Функція мовою С, арксинуси

#include <stdio.h>
#include <math.h>
float arcsinus(float);
int main()
{
    float z, y, Q, k; 
    printf("Уведіть Z\t");
    scanf("%f", &z);
    printf("\nУведіть Y\t");
    scanf("%f", &y);
    if((z>1||z<-1)||(y>1)||(y<-1))
      printf("\nУведіть інші значення");
      else if(((z>-1)&&(z<1))&&((y>-1)&&(y<1))){ 
          Q=(2+arcsinus(z))/(5-fabs(arcsinus(y)*arcsinus(y)-arcsinus(z)));
          printf("\nQ=%f",Q);
      }
    return 0;
}
float arcsinus(float X){
    float sum=X;
    for(float n=1;n<12;n++)
      sum+=(2*n-1)*pow(X,(2*n+1))/(2*n)*(2*n+1);
return sum;
}

Я спробувала так. На разі цим задоволена *YAHOO* . Дякую всім, особливо тим, хто скаже, чи правильна формула арккосинуса і що з нею робити, якщо ні [:}

Подякували: koala1

8

Re: Функція мовою С, арксинуси

Lata написав:

Ні, які би відступи я не робила результат - той самий.

Відступи насправді не змінюють нічого, крім зручності коду для читання людиною — на роботу програми вони не впливають, але неправильні відступи можуть заплутати програміста й змусити його зробити вже справжні помилки. Звичайно, якщо не йдеться про python (де відступи виконують ту ж роль, що фігурні дужки С-подібних мовах), але в даному випадку це С — тут це просто правило оформлення коду, що допомагає краще бачити структуру програми.

Подякували: koala, Lata2

9

Re: Функція мовою С, арксинуси

Вам компілятор, швидше за все, видає купу попереджень. Їх теж бажано виправляти.
Ну і

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

float arcsinus(float);
float formula(float, float);

int main()
{
    //це - перевірка функції арксінуса. Видаліть її...
    for(int i=2;i<6;++i)
        printf("%f %f\n", arcsinus(1.0/i), (float)asin(1.0/i));
    //...а можете порівняти з власною функцією
    
    float z, y, q; 
    printf("Уведіть Z = \t");
    scanf("%f", &z);
    printf("\nУведіть Y = \t");
    scanf("%f", &y);
    if( fabs(z)>=1.0 || fabs(y)>=1.0 ) //дослівно з умови
      printf("\nУведіть інші значення");
    else { //гілка else виконується лише якщо не виконалася if, тому не треба ще раз перевіряти
          q = formula(z,y);
          printf("\nQ=%f",q);
    }
    return 0;
}

float formula(float z, float y)
{
    float asinz = arcsinus(z);
    float asiny = arcsinus(y); //обчислюємо складні величини пр одному разу
    return (2+asinz)/(5-fabs(asiny*asiny-asinz));
}
float arcsinus(float x)
{
    // тут будемо обчислювати фрагмент елементу суми, що повторюється
    // і множити й ділити його на кожній ітерації
    float sum = 0.0;
    float part = x; 
    for(int n=0;n<20;++n){ //20 взяв навмання, щоб не було вічного циклу
        float element = part/(2*n+1);
        sum += element;
        if(fabs(element)<1e-6)
            break; //якщо елемент замалий - виходимо
        part *= x*x * (2*n+1)/(2*n+2); 
        //якщо обчислювати кожен елемент суми в кожній ітерації, то необхідно
        //буде робити вкладений цикл. Якщо така формула заскладна - переробіть
    }
    return sum; //це можна було поставити замість break
}
Подякували: Lata1

10

Re: Функція мовою С, арксинуси

Компілятор насправді не видає попереджень. Дякую всім!