Квадратный корень в си шарп
Консольное приложение вычисление квадратного корня на С#
Это консольное приложение которое производит вычисление квадратного корня через дискриминант.
Эта прога написанна в муках, по этому не судите строго.
Я только начал изучать прекрасный язык программирования С#.
Хотя раньше писал только на Vb . Но надо двигаться вперед.
Console.WriteLine(«X1 = , X2 = <1>«, x1, x2);
Что ты хотел сказать этим коментарием?
Console.WriteLine(«X1 = , X2 = <1>«, x1, x2);
Console.WriteLine(«X1 = , X2 = <1>«, x1, x2);
Не «вычисление квадратного корня», а «вычисление корней квадратного уравнения», е-мае!
Прежде чем писать свои мысли надо разбираться в этом. И запомни от перемены мест слагаемых сумма не меняется. Квадратное уравнение — уравнение вида ax2 + bx + c = 0, где a ≠0. Переменная х называется корнем квадратного уравнения. Думай прежде чем написать что нибуть. А еще лучше учи математику.
Met 🙂
1) ты доказал именно то, про что я и написал.
2) я учусь в университете на математическом, можешь мне не указывать 🙂
Это сразу заметно. Ты учишся а я закончил Физтех. И если ты учишся на математическом в чем я сомневаюсь то ты должен знать простую истинну, что от перемены мест слагаемых сумма не меняется. Вот когда будеш учиться в физтехе, тогда и будеш умничать а пока слушай что тебе старшие говорят и думай прежде чем что то ляпать.
Ну а если совсем по правилам то Решения квадратного уравнения через дискриминант.
Да если ты учишся на математическом то ты наверное знаеш что такое Неполные квадратные уравнения. Попробуй написать программу для решения этих уравнений и тогда мосмотрим. Я думаю формулу ты знаеш. А критиковать это каждый может и придираться к словам. Здесь тебе не лингвистический сайт. Или ты считаеш себя очень хорошим программистом ?.
ты мне прям настроение с утра поднял, спасибо)
Это тебе спасибо. Повесилил от души. Продолжай в таком духе. Теперь я знаю к кому обратиться по поводу слов в тексте.
Мет, ты действительно говнокодер. Твой код выглядит ужасно, манера выставлять цвет в консоли убивает. Те цвета, что ты ставишь, делают программу вырвиглазной и невозможной для адекватного использования.
Полное отсутствие форматирование вообще меня убило. Ты молодец, друг, физтех закончил. Ума не прибавилось, как я вижу.
Поучи-ка лучше русский, почитай книжки о том, как надо форматировать код, и не трожь тех, кто говорит тебе правильные вещи.
И да, черт возьми, я вернулся!
Ну вот еще один прыщик проклюнулся. Кулхацкер ты молодец давай жги. Я же еще раз говорю что дурная голова рукам покоя не дает.
Ну а что касается форматирования кода, то каждому своё, и если ты знаеш С# в чем я сомневоюсь, то цвет текста и остальные цвета можно создавать по своему усмотрению. И если я так поставил цвета то это не значит что надо за мной повторять один в один ну если конечно ты не дибил. Программа написана просто для примера и ознакомления а остальное дело вкуса.
Мет-мет, большей оригинальности я и не ожидал.
Я смотрю вам девчата заняться не чем, выб лучше Лукина почитали да «Дискретная математика для программистов» тоже надо по изучать особенно тебе Кулхацкер да и твоему товарищу тоже не мешает. А то переписывать програмки с книг и говорить что это шедевр ума много не надо. Ну а в остальном вы молокососы на правельном пути. Удачи.
Met, есть ли в твоей жизни хоть что-нибудь, в чем ты не сомневаешься?)
Да-да. Я молокосос на правильном пути.
Чувствую я, что сие плавно в срач перерастет.
Ничего, главврач следит, санитары на стреме.
за вами с мобильника следить еле успеваю)
Слезь с мобильника. Работа есть.
мет, ты либо дурачок, либо тролль (в чем я сильно сомневаюсь). Все, что ты написал, напрямую относится именно к твоей статье)
Лайс, я где-нибудь, хоть в одной из своих статеек сказал, что она шедевр?
Хотя, не будем срач разводить.
Нда, весело тут у вас.
А чего нет никакой защиты от дурака. А если я буквы введу, или вместо точки запятую? Или ноль забью в переменную ‘a’ и начнется деление на ноль?
Кроме Console.WriteLine(«X1 = X2 = <1>«, x1, x2);(показали вывод нескольких аргументов строки вывода)
и Console.ForegroundColor = ConsoleColor.DarkCyan; (консольные разукрашки) стоит обратить внимание только на Math.Sqrt(D).
Но если это и есть цели урока, то тема НЕ раскрыта.
Ни ConsoleColor, ни WriteLine, ни Math.
Klinsman, Тут статьи не профессионалы пишут, а те кто ещё новички в программировании, если у вас есть хорошие знания по программированию, то можете написать несколько хороший статей!
Квадратный корень в си шарп
Разделы
Быстрое вычисление квадратного корня на Си
При программировании микроконтроллеров разработчики иногда сталкиваются с проблемой вычисления квадратного корня. Например, данная операция требуется при выполнении быстрого преобразования Фурье или вычислении среднеквадратического значения сигнала.
В стандартной библиотеке Си – math.h, есть функция для вычисления квадратного корня sqrt(), которой при желании можно воспользоваться. Она работает с числами типа float, обеспечивает высокую точность результата, но требует для своей работы длительного времени. Для микроконтроллера AVR это порядка 3000 циклов тактовой частоты (проверено в компиляторе IAR на разных уровнях оптимизации).
Если к точности вычисления корня не предъявляются высокие требования, можно воспользоваться упрощенным алгоритмом, занимающим меньше места в памяти и выполняющим вычисления в несколько раз быстрее.
Алгоритм выглядит так.
Как мне подсказали умные люди, алгоритм основан на итерационной формуле Герона.
где А – фиксированное положительное число, а X1 – любое положительное число.
Итерационная формула задаёт убывающую (начиная со 2-го элемента) последовательность, которая при любом выборе X1 быстро сходится к квадратному корню из числа А.
Ради интереса я переписал алгоритм в явном виде. Скомпилированный, он ничуть не потерял ни в быстродействии, ни в объеме. Объем даже на пару байтов уменьшился.
Недостатки приведенного кода в том, что он работает только с целыми 16-ти разрядными числами и при больших значениях аргумента вычисления становятся не точными. Правда, точность вычислений можно повысить, добавив еще несколько итераций, но за это естественно придется платить быстродействием.
Код занимает прядка 70 байт и выполняется
за 700 циклов. Данные получены в компиляторе IAR AVR при medium оптимизация по скорости.
Точность вычисления данного алгоритма можно оценить по приведенному ниже графику. Синий график построен по значениям, полученным c помощью библиотечной функции sqrt(), красный график по значениям функции root().
В ходе обсуждения моей заметки, те же самые умные люди подсказали еще один алгоритм вычисления квадратного корня.
Related items
Comments
подскажите пожалуйста как проделать это с переменной типа long?
80 байтов), — скорость выполнения (
1000 циклов для AVR).
Напишу как делаеться в AVR Studio. Пишеться код — компилим,смотри м сколько занял,добавляем функцию — и смотрим новий размер кода. Разница между новым и старым значение есть размер функции.
Для скорости выполнения. ставим брейкпойнт перед вызовом функции и после,запускаем симуляцию — обнуляем cycle counter,запуска ем симуляцию — и новое значение будеть скоростью выполнения (также можно увидеть сколько время исполняеться функция в мкс или мс).
Для IAR`a . Нужно включить опцию создания листинга программы. Project > Options > C/C++ Compiler > List галочка Output list file. Если включить еще и Assembler mnemonics в lst файле будет ассемблерный код, сгенерированный компилятором из твоей программы. Эта информация полезна для оптимизации сишного кода, конечно, если ты знаешь ассемблер.
Затем запускаешь компиляцию проекта и с левой стороны (в окне отображения структуры проекта) ищешь файлы с расширением *.lst Они будут созданы для каждого программного модуля. В конце этого файла есть табличка со списком функций и значениями занимаемой памяти.
Чтобы прикинуть скорость выполнения какого-нибудь куска кода (обычно функции), я прогоняю этот код в программном симуляторе IAR`a. Включаю опцию Project > Options > Linker > Debug Information . Запускаю компиляцию и отладку с помощью кнопки Debug (Ctrl+D). Устанавливаю брейкпоинты, открываю окно с регистрами микроконтроллер а (меню View > Register) и запускаю код на выполнение по шагам (F11) или непрерывно (f5). В окне регистров в разделе CPU Register есть строка CYCLES. Она отображает число прошедших тактов. По показаниям этого числа можно прикинуть сколько тактов занимает выполнение функции.
То же самое можно делать и в AVR Studio. Там это даже лучше получается, потому что студия моделирует прерывания, а IAR нет.
F = 8 MHz, ATmega8, optimization O0 (none):
размер 14 байт.
скорость 540 циклов — 67.5uS
F = 8 MHz, ATmega8, optimization Os (none):
размер 14 байт.
скорость 2 циклf — 0.25uS
Код которий тестировал:
unsigned int value = 0;
unsigned int isqrt(unsigned int x)
<
unsigned int m, y, b;
m = 0x4000;
y = 0;
while (m != 0)
<
b = y | m;
y = y >> 1;
int main(void)
<
asm(«nop»);
value = isqrt(4096);
asm(«nop»);
Пользовался детским алгоритмом, на мой взгляд достаточно быстр и достаточно компактный. Идея в том что от числа последовательно отнимаются все нечётные числа, и сколько вычитаний удалось сделать, таков и корень числа. Пример, число 49;
1) 49 — 1 = 48
2) 48 — 3 = 45
3) 45 — 5 = 40
4) 40 — 7 = 33
5) 33 — 9 = 24
6) 24 — 11 = 13
7) 13 — 13 = 0
7 циклов, корень числа 49 — 7.
И кстати при работе с МК типа AVR-ки лучше избегать делений, т.к. у AVR ядра нет аппаратного деления, а программное занимает дофига тактов. Другое дело ARM Cortex-M3 и выше, у которых деление выполняется за 2. 12 тактов.
У функции корня есть некоторые свойства симметрии, которые позволяют вычислять ее только на некотором отрезке, а потом решение распространить на всю ось. Например,
sqrt(a*2^16)=2^ 8*sqrt(a).
Удобно в качестве такого отрезка взять значения [2^30-2^31), потому что остальные значения можно свести к нему побитовым сдвигом и при этом не будет происходить потеря точности. Сначала вычисляем первый значащий бит (программно половинным делением или процессорной инструкцией, например на ARM это __clz). Потом сдвигаем входное число на это кличество бит и вычисляем корень, полученное значение сдвигаем обратно на в два раза меньшее количество).
Для вычисления корня на отрезке интерполируем его многочленом Лагранжа (параболой). Например, возьмем в качестве точек многочлена 2^30, 1,5 * 2^30, 2^31. Можно воспользоваться сторонним сервисом, и не возиться с вычислением коэффициентов. У меня получилась такая формула:
-x^2/499100218444523 + x/52370 + 14575
Очевидно, напрямую её использовать нельзя, потому что значения не влазят даже в диапазон целых. Но надо учесть, что нам важны только 16 бит результата, поэтому можно немного схитрить и вынести что-то за скобки.
(-x/9530269590 + 1) * x/52370 + 14575
(-x/145420 + 65536) * (x/65536) / 52370 + 14575
Ну и последнее — заменить деление на умножение. Допустим, у нас в резерве 30 бит числа. Мы хотим поделить некое число x, например, на 543. Вычисляем, в числе 543 есть 10 бит, в х 16 бит.
x / 543 * 2^26 / 2^26
x * (2^26 / 543) / 2^26
x * 123589 / 2^26
Теперь эти знания применяем к своему многочлену.
(-x/2^14 * 7384 / 2^16 + 2^16) * (x/2^16) / 2^16 * 20503 / 2^14 + 14575
Не ручаюсь за правильность коэффициентов, надо внимательно проверить.
Когда писал, не учел одну штуку, число бит может быть нечетным, отрезок надо брать больше.
Естественно, алгоритм будет быстро работать при наличии аппаратного умножения.
Извлечение квадратного корня с помощью нормальных алгоритмов Маркова
Захотел я однажды вычислить квадратный корень с помощью нормальных алгоритмов Маркова (НАМ).
Кратко о НАМ:
- Существует список замен одной подстроки на другую, называемых правилами
- Ищем с начала списка первое правило которое можем применить и применяем его для первого вхождения
- Если такое правило было обнаружено, то возвращаемся к предыдущему пункту и просматриваем список правил сначала
- Если правило было заключительным, то завершаем работу
- Если больше нет правил, которые мы можем применить, то завершаем работу
Итак, вроде бы все просто? Однако, как писать программы на НАМ?
Для себя я сделал примерно такой план:
- Пытаемся написать обычный алгоритм использующий только строки
- Следим за тем, чтобы последние замены не пересекались с первыми
- Переворачиваем алгоритм и записываем с конца к началу
Итак, вернемся к вычислению квадратного корня. Мы будем использовать «детский» метод (он же арифметический), который основывается на том простом факте, что квадрат числа — это сумма нечетных чисел от 1 до 2n-1:
- 1 = 1 2 = 1
- 1 + 3 = 2 2 = 4
- 1 + 3 + 5 = 3 2 = 9
Как бы мы могли реализовать извлечение корня основываясь на этом свойстве? Мы будем последовательно отнимать от числа сначала 1, потом 3, потом 5 и т.д., пока число не станет меньше нуля, паралельно считая сколько отниманий мы сделали. Итого, уже два счетчика + одна переменная для хранения результата
Маленькая особенность НАМ — нету здесь чисел. И переменных нету. Поэтому нам надо бы симулировать их. Так как писать длинную арифметику мне было лень (да и сомневаюсь что это возможно человеку), то арифметические операции сделал по простому принципу — с помощью инкремента и декремента.
Я решил сделать так, чтобы у меня строка хранилась в формате <Результат>.<Число><ОчередноеНечетноеЧисло><ИндикаторКонцаСтроки>
Нечетное число я решил хранить в унарной системе исчисления и обозначать единицу как «#» — так гораздо проще работать будет.
Теперь, каким образом мы будем отнимать от числа очередное нечетное, не потеряв данные? Я решил, что между нечетным число и индикатором конца строки нужно добавить маркер «a», который перемещаясь сквозь число будет его дублировать, но уже в другом виде (обозначаем через «-«). После будем сдвигать все минусы к числу и отнимать их. После того как мы все числа отняли, нам нужно увеличить результат на единицу.
В моей реализации была маленькая особенность — результат всегда выходит округленным вверх. Я решил сделать так, чтобы этот алгоритм работал с абсолютной точностью 0.5, а не 1 (как в описании). Когда в строке остается минусов больше чем половина от их начального значения, мы должны взять и уменьшить результат.
В итоге получился «пинг-понг», который извлекает квадратный корень заданного числа.
Очень интересно выглядит зависимость количества замен от числа: