Как возводить в степень в си

от admin

Арифметические операторы на языке C

Компилируемый язык Си поддерживает все стандартные арифметические операции:

  • умножение;
  • деление;
  • сложение;
  • вычитание;
  • возведение в степень и прочие.

Одни из них осуществляются с помощью обычных операторов (плюсов, минусов, звёздочки, знака процентов), другие — специальных функций, которые содержаться в основном в библиотеке math.h. Операторы принято делить на тернарные, унарные, базовые бинарные, лево-присевающие бинарные и тернарные.

В данной статье идёт речь, прежде всего, об арифметических операциях и операторах, связанных с ними. Чем префикс отличается от постфикса? Как и почему нельзя найти остаток от деления у вещественных чисел? Как использовать static_cars?

Арифметика в Си и Си++

Присваивание

Позволяет присваивать переменной некоторое значение согласно типу, с помощью которой переменная была инициализирована.

Оператор » = «.

int a_1 = 16;
double a_2 = 12.6;
flout a_3 = 13.3;
char a_4 = 255;
bool a_5 = 3;

Не путать с оператором сравнения ==, который применяется главным образом в условиях и циклах!

Примечание: Далее будут встречаться операторы » += «, » -= «, » *= «, » %= » и » /= «. Их тоже относят к операторам присваивания, но для большего раскрытия материла они занесены в другой раздел.

Сложение и вычитание.

Используется для нахождения соответственно суммы и разности инициализированных переменных или чисел.

Оператор » + » для сложения и » — » для вычитания.

int a = 3, b = 6;
int c_1 = a+b, c_2 = a-b; // c_1 = 9 и c_2 = -3
int c_3 = c + t; // выдаст ошибку, так как переменная t не инициализирована
int c_4 = 4 + 5; // c_4 = 9

Часто для сложения и вычитания используют операторы » += » и » -= «, но их больше относят к операторам присваивания. Они используются для упрощения записи кода программы.

Пример:

int c_5 += 5; // соответствует записи c_5 = c_5 + 5
int c_6 -= 12; // соответствует записи c_6 = c_6 — 12

Инкремент

В зависимости от того, является ли оператор префиксным или постфиксным, прибавляет единицу или сразу при присвоении, или позже. Инкремент удобно использовать в циклах for, while и do…while.

Оператор » ++n » для префиксной и » n++ » для постфиксной переменной n.

int a = 3;
int b = 3;
int x1 = a++; // x1 = 3
int x2 = ++b; // x2 = 4

Декремент

В зависимости от того, является ли он префиксным или постфиксным, вычитает единицу или сразу, или позже. Как и в случае с инкрементом, декремент тоже используется при записи циклов.

Оператор » —n » для префиксной и » n— » для постфиксной переменной n.

int a = 3;
int b = 3;
int x1 = a—; // x1 = 3
int x2 = —b; // x2 = 2

Деление

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

main.cpp:17:11: warning: division by zero [-Wdiv-by-zero]
Floating point exception (core dumped)

Оператор » / «.

double a = 3.5, b = 1.9;
int c = a / 0; // warning!
int c_1 = a / b; // c_1 = 1
double c_2 = a / b; // c_2 = 1.84211
float c_3 = a / b; // c_3 = 1.84211
bool c_4 = a / b; // c_4 = 1

Оператор » /= » так же используется для деления целых и вещественных чисел.

int c_5 /= b; // соответствует записи c_5 = c_5 / b

Умножение

Позволяет находить произведение переменных и чисел. В зависимости от типа переменных выдаётся или целочисленный, или вещественный результат.

Оператор » * «.

double a = 3.5, b = 1.9;
int c_1 = a * b * 2; // c_1 = 13
double c_2 = a * b * 2; // c_2 = 13.3
float c_3 = a * b; // c_3 = 6.65
bool c_4 = a * b; // c_4 = 1

Оператор » *= » так же используется для перемножения целых и вещественных чисел чисел.

int c_5 *= b; // соответствует записи c_5 = c_5 * b

Не путать с указателями, которые тоже обозначаются звёздочкой!

Остаток от деления

В языках Си и Си++ данная операция используется только с целыми числами. При работе с такими типами, как float и double, нужно смотреть за корректностью выполнения программы. В одних случаях, их использование с оператором проходит без особых проблем, а в других — выдаёт ошибки компиляции.

Оператор » % «.

int a = 16, b = 8, d = 9;
int c_1 = a % b; // c_1 = 0
int c_2 = d % b; // c_2 = 1
int c_3 = b % d; // c_3 = 8
float c_4 = b % d; // c_4 = 8 -> ошибки нет
float a1 = 16, b1 = 8, d1 = 9;// error.
int c_5 = a1 % b1;

Оператор » %= » для данный операции тоже можно использовать.

int c_6 %= b; // соответствует записи c_6 = c_6 % b

Остаток от деления вещественных чисел

Операция остаток от деления у вещественных чисел невозможна, так как в процессе деления как таковой остаток вообще нельзя получить. Однако, если даны вещественные значения и оператор static_cast, можно без проблем применить данный оператор.

Читать:
Определите на какую высоту

Пример:

double a = 16.8, b = 8.3, d = 9.6;
auto a_1 = static_cast (a);
auto b_1 = static_cast (b);
auto d_1 = static_cast (d);
int c_1 = a_1 % b_1; // c_1 = 0
int c_2 = d_1 % b_1; // c_2 = 1
int c_3 = b_1 % d_1; // c_3 = 8

Чем отличаются унарные, бинарные и тернарные операторы?

Всего существует два унарных оператора: плюс » + » и минус » — «. Оба пишутся непосредственно перед операндом. Унарный плюс редко используется, так как он возвращает значение операнда. К бинарным относят сложение » + «, вычитание » — «, умножение » * «, деление » / «, остаток от деления » % «. Таким образом, есть всего 5 операций, которые применяются к 2-м операндам.

В языке Си существует только один тернарный оператор, который является условной операцией » ? : «, состоящей из трёх операндов. В общем виде запись тернарного оператора выглядит так:

условие ? выражение_1 : выражение_2

Если условие верно или истинно, то выполняется выражение_1. В противном случае выражение_2.

Пример:

int a = 3, b = 6;
a == b ? cout b ? cout
#include
using namespace std;
int main() <
cout

Pow – возведение числа в степени

При успешном завершении, pow возвращает вычисленное значение, x^y.

Иногда, аргумент посылаемый pow вызывает в результате переполнение, или он вообще может быть не вычислимым. При переполнении, pow возвращает значение HUGE_VAL. При слишком большом значении, глобальной переменной errno присваивается значение:
ERANGE — Результат выходит за пределы.

Если аргумент x меньше или равен 0, и y не равен
0, то при этом errno присваивается значение:
EDOM — Ошибка области определения.
и функция возвращает значение обратное HUGE_VAL.

Если и x и y равны 0, то pow возвращает 1.
Обработку ошибок функции pow можно изменить с помощью функции matherr.

Переносимость

Вещественная версия pow доступна в системах UNIX и поддерживается стандартом ANSI C. Комплексная версия требует С++ и поэтому скорее всего непереносима.

Возведение числа в степень Си

Не понимаю, как правильно реализовать, если у степени есть десятичная часть. Точнее я сделал это, но при 3х знаках после запятой у степени, там уже получается возведение в 1000 степень и на это тратится секунд 5. При 4х знаках после запятой уже ловлю seg fault.

Harry's user avatar

Это решение кажется вам слишком простым? Согласен. Решим задачу без использования <math.h>.

Идею подсказал eri. Я ему благодарен.

Например 1.5 10.625 . Переведём показатель в двоичную систему счисления: 10.62510 = 1010.1012:

Множители в правом столбце получаются последовательным возведением основания в квадрат для положительных бит. Для отрицательных бит надо последовательно извлекать квадратные корни.

Когда таблица составлена, надо перемножить числа соответствующие единичным битам:

1.5 10.625 = 25.62890625 · 2.25 · 1.22474487 · 1.05198951 = 74.29671764.

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

Собственная функция возведения в степень Си?

Даже без рекурсии. Ничего не изменится, если я заменю внутри функции на обычные pow.

В рекурсию передаются целые степени, поэтому больше 1го раза в рекурсию он не зайдёт.

Pudjak, давай разделим две проблемы. Первая — segfault. Неправильный доступ к памяти.

Вторая — численный метод который очень долго работает. Скорее всего ты взял из справочника
метод с очень медленной сходимостью. Надо поискать именно тот который реализован в
функции pow и для начала просто его повторить.

С чем мы сейчас боремся?

Я скажу честно что я не компилировал и не анализировал твой код.
Все что я пишу — это набор механических советов или трансформаций
кода нацеленных на выявление причины сегфолта.

Я тебя попросил в первом посту измерять глубину рекурсии. Сделай пожалуйста это. Это очень легко.
Залоггируй. Иначе мы топчемся на месте.

Похожие статьи