ДЗ 2 — Формулы, ветвления и табуляция
Задачи на вычисление выражений, проверку области определения и вывод таблиц значений.
Редактировать источникЧто внутри
Во втором домашнем задании акцент смещается с простого ввода на вычисление формул, проверку корректности аргументов и вывод серий значений.
2.1 «Конус»
Условие. Нужно вычислить объём и полную поверхность усечённого конуса по R, r и h.
Как устроено решение. Программа читает размеры, вычисляет образующую l, затем по формулам получает объём V и площадь S.
Что учесть. В сохранённом исходнике pi объявлена как int, поэтому значение 3.14 обрезается до 3. В разборе важно понимать, что сама идея верна, но точность страдает.
#include <iostream>
#include <math.h>
#include <cmath>
using namespace std;
int main()
{
int l;
int pi = 3.14;
float R, r, h, V, S;
cout << "Enter h: ";
if (cin >> h && h >= 0)
{
cout << "Enter r: ";
if (cin >> r && r >= 0)
{
cout << "Enter R: ";
if (cin >> R && R >= 0)
{
l = sqrt(h * h + (R - r) * (R - r));
pi = 3.14;
V = (((pi * h) / 3) * (R * R + r * R + r * r));
S = (pi * (R * R + (R + r) * l + (r * r)));
cout << "V: " << V << "\n";
cout << "S: " << S;
}
else
{
cout << "Immposible";
return 0;
}
}
else
{
cout << "Immposible";
return 0;
}
}
else
{
cout << "Immposible";
return 0;
}
}2.2 «Разветвление»
Условие. Для введённых x и a нужно вычислить значение кусочной функции.
Как устроено решение. Сохранённый файл работает по двум веткам: если |x| < 1, считается w = a * log(|x|), иначе программа пытается найти w = sqrt(a - x^2).
Что учесть. Здесь хорошо видно, зачем проверять область определения: логарифм требует положительный аргумент, а корень требует неотрицательное подкоренное выражение.
#include <iostream>
#include <cmath>
using namespace std;
int main() {
setlocale(0, "");
double x, a, w, xm;
cout << "Введите X:";
cin >> x;
cout << "Введите A:";
cin >> a;
if (cin.fail()) {
cin.clear();
cin.ignore();
cout << "Некорректный ввод! Перезапустите приложение." << endl;
return 0;
}
else {
cout << "Ввод успешен." << endl;
xm = fabs(x);
if (x == 0)
{
cout << "Eror";
return 0;
}
else if (xm < 1)
{
w = a * log(xm);
}
else if (xm >= 1) {
if ((a - x * x) < 0) {
cout << "Ответ: отрицательное подкоренное выражение! Нет ответа.";
return 0;
}
else {
w = sqrt(a - x * x);
}
}
}
cout << "Ответ: " << w;
return 0;
}2.3 «Функция»
Условие. Нужно вычислить выражение от b, x и y с логарифмом и квадратным корнем.
Как устроено решение. В текущем варианте сначала считаются j = b - y и u = b - x, затем при корректной области определения программа выводит z = log(j) * sqrt(u).
Что учесть. Для такой задачи критично уметь назвать ограничения: b - y > 0, а b - x >= 0. Именно эти проверки защищают программу от некорректных вычислений.
#include <iostream>
#include <math.h>
#include <cmath>
using namespace std;
int main()
{
float x, y, b, z;
int j, u;
cout << "Enter B: ";
if (cin >> b)
{
cout << "Enter X: ";
if (cin >> x)
{
cout << "Enter Y: ";
if (cin >> y)
{
j = b - y;
u = b - x;
if (j > 0)
{
if (u != 0) {
z = log(j) * sqrt(u);
cout << "Answer: " << z;
return 0;
}
else if (u = 0)
{
cout << "Net resh";
}
}
else
{
cout << "Net resh";
return 0;
}
}
else
{
cout << "Eror";
return 0;
}
}
else
{
cout << "Eror";
return 0;
}
}
else
{
cout << "Eror";
return 0;
}
}2.4 «Порядок»
Условие. Нужно вывести 10 натуральных чисел подряд, начиная с корректного значения N.
Как устроено решение. Исходник читает N, задаёт границу N + 10 и печатает числа в цикле while.
Что учесть. В PDF отдельно оговариваются дробные, нулевые и отрицательные случаи. В текущем файле они не обработаны: решение работает как простая печать десяти последовательных целых чисел от введённого N.
#include <iostream>
#include <math.h>
#include <cmath>
using namespace std;
int main()
{
int N, N10;
cout << "Enter N: ";
if (cin >> N)
{
N10 = N + 10;
while (N != N10)
{
cout << N << ", ";
N = N + 1;
}
}
else
{
cout << "Eror";
return 0;
}
}2.5 «Табуляция»
Условие. Нужно протабулировать функцию на отрезке от -4 до 4 с шагом 0.5.
Как устроено решение. В сохранённой программе табулируется выражение y = (x^2 - 2x + 2) / (x - 1). Значения от -4 до 0 и от 1.5 до 4 печатаются отдельно, чтобы не попасть на деление на ноль при x = 1.
Что учесть. Это хороший пример, где область определения влияет не только на вычисление, но и на организацию цикла.
#include <stdlib.h>
#include <math.h>
#include <iostream>
using namespace std;
int main() {
setlocale(0, "");
double y;
for (double x = -4; x <= 0; x = x + 0.5) {
y = (((x * x) - 2 * x + 2) / (x - 1));
cout << "Ответ для x = " << x << " y = " << y << endl;
}
cout << "Ответ для x = 1 не существует" << endl;
for (double x = 1.5; x <= 4; x = x + 0.5) {
y = (((x * x) - 2 * x + 2) / (x - 1));
cout << "Ответ для x = " << x << " y = " << y << endl;
}
return 0;
}