Sin в c как записать

от admin

Функция sin() в C++

Функция sin() в C++ возвращает синус угла (аргумента) в радианах.

Эта функция определена в заголовочном файле <cmath>.

прототип sin() (в соответствии со стандартом C ++ 11)

Параметры

Функция sin() принимает единственный обязательный аргумент в радианах.

Возвращаемое значение

Функция sin() возвращает значение в диапазоне [-1, 1]. Возвращаемое значение может быть в формате double, float или long double.

How does C compute sin() and other math functions?

I’ve been poring through .NET disassemblies and the GCC source code, but can’t seem to find anywhere the actual implementation of sin() and other math functions. they always seem to be referencing something else.

Can anyone help me find them? I feel like it’s unlikely that ALL hardware that C will run on supports trig functions in hardware, so there must be a software algorithm somewhere, right?

I’m aware of several ways that functions can be calculated, and have written my own routines to compute functions using taylor series for fun. I’m curious about how real, production languages do it, since all of my implementations are always several orders of magnitude slower, even though I think my algorithms are pretty clever (obviously they’re not).

22 Answers 22

In GNU libm, the implementation of sin is system-dependent. Therefore you can find the implementation, for each platform, somewhere in the appropriate subdirectory of sysdeps.

One directory includes an implementation in C, contributed by IBM. Since October 2011, this is the code that actually runs when you call sin() on a typical x86-64 Linux system. It is apparently faster than the fsin assembly instruction. Source code: sysdeps/ieee754/dbl-64/s_sin.c, look for __sin (double x) .

This code is very complex. No one software algorithm is as fast as possible and also accurate over the whole range of x values, so the library implements several different algorithms, and its first job is to look at x and decide which algorithm to use.

When x is very very close to 0, sin(x) == x is the right answer.

A bit further out, sin(x) uses the familiar Taylor series. However, this is only accurate near 0, so.

When the angle is more than about 7°, a different algorithm is used, computing Taylor-series approximations for both sin(x) and cos(x), then using values from a precomputed table to refine the approximation.

When |x| > 2, none of the above algorithms would work, so the code starts by computing some value closer to 0 that can be fed to sin or cos instead.

There’s yet another branch to deal with x being a NaN or infinity.

This code uses some numerical hacks I’ve never seen before, though for all I know they might be well-known among floating-point experts. Sometimes a few lines of code would take several paragraphs to explain. For example, these two lines

are used (sometimes) in reducing x to a value close to 0 that differs from x by a multiple of π/2, specifically xn × π/2. The way this is done without division or branching is rather clever. But there’s no comment at all!

Older 32-bit versions of GCC/glibc used the fsin instruction, which is surprisingly inaccurate for some inputs. There’s a fascinating blog post illustrating this with just 2 lines of code.

fdlibm’s implementation of sin in pure C is much simpler than glibc’s and is nicely commented. Source code: fdlibm/s_sin.c and fdlibm/k_sin.c

Functions like sine and cosine are implemented in microcode inside microprocessors. Intel chips, for example, have assembly instructions for these. A C compiler will generate code that calls these assembly instructions. (By contrast, a Java compiler will not. Java evaluates trig functions in software rather than hardware, and so it runs much slower.)

Chips do not use Taylor series to compute trig functions, at least not entirely. First of all they use CORDIC, but they may also use a short Taylor series to polish up the result of CORDIC or for special cases such as computing sine with high relative accuracy for very small angles. For more explanation, see this StackOverflow answer.

John D. Cook's user avatar

OK kiddies, time for the pros. This is one of my biggest complaints with inexperienced software engineers. They come in calculating transcendental functions from scratch (using Taylor’s series) as if nobody had ever done these calculations before in their lives. Not true. This is a well defined problem and has been approached thousands of times by very clever software and hardware engineers and has a well defined solution. Basically, most of the transcendental functions use Chebyshev Polynomials to calculate them. As to which polynomials are used depends on the circumstances. First, the bible on this matter is a book called «Computer Approximations» by Hart and Cheney. In that book, you can decide if you have a hardware adder, multiplier, divider, etc, and decide which operations are fastest. e.g. If you had a really fast divider, the fastest way to calculate sine might be P1(x)/P2(x) where P1, P2 are Chebyshev polynomials. Without the fast divider, it might be just P(x), where P has much more terms than P1 or P2. so it’d be slower. So, first step is to determine your hardware and what it can do. Then you choose the appropriate combination of Chebyshev polynomials (is usually of the form cos(ax) = aP(x) for cosine for example, again where P is a Chebyshev polynomial). Then you decide what decimal precision you want. e.g. if you want 7 digits precision, you look that up in the appropriate table in the book I mentioned, and it will give you (for precision = 7.33) a number N = 4 and a polynomial number 3502. N is the order of the polynomial (so it’s p4.x^4 + p3.x^3 + p2.x^2 + p1.x + p0), because N=4. Then you look up the actual value of the p4,p3,p2,p1,p0 values in the back of the book under 3502 (they’ll be in floating point). Then you implement your algorithm in software in the form: (((p4.x + p3).x + p2).x + p1).x + p0 . and this is how you’d calculate cosine to 7 decimal places on that hardware.

Note that most hardware implementations of transcendental operations in an FPU usually involve some microcode and operations like this (depends on the hardware). Chebyshev polynomials are used for most transcendentals but not all. e.g. Square root is faster to use a double iteration of Newton raphson method using a lookup table first. Again, that book «Computer Approximations» will tell you that.

If you plan on implmementing these functions, I’d recommend to anyone that they get a copy of that book. It really is the bible for these kinds of algorithms. Note that there are bunches of alternative means for calculating these values like cordics, etc, but these tend to be best for specific algorithms where you only need low precision. To guarantee the precision every time, the chebyshev polynomials are the way to go. Like I said, well defined problem. Has been solved for 50 years now. and thats how it’s done.

Читать:
Как изменяется показания амперметра если движок реостата передвинуть вправо почему

Now, that being said, there are techniques whereby the Chebyshev polynomials can be used to get a single precision result with a low degree polynomial (like the example for cosine above). Then, there are other techniques to interpolate between values to increase the accuracy without having to go to a much larger polynomial, such as «Gal’s Accurate Tables Method». This latter technique is what the post referring to the ACM literature is referring to. But ultimately, the Chebyshev Polynomials are what are used to get 90% of the way there.

sin, sinf, sinl

If no errors occur, the sine of arg ( sin(arg) ) in the range [-1 ; +1] , is returned.

The result may have little or no significance if the magnitude of arg is large.

If a domain error occurs, an implementation-defined value is returned (NaN where supported).

If a range error occurs due to underflow, the correct result (after rounding) is returned.

[edit] Error handling

Errors are reported as specified in math_errhandling.

If the implementation supports IEEE floating-point arithmetic (IEC 60559),

  • if the argument is ±0, it is returned unmodified
  • if the argument is ±∞, NaN is returned and FE_INVALID is raised
  • if the argument is NaN, NaN is returned

[edit] Notes

The case where the argument is infinite is not specified to be a domain error in C, but it is defined as a domain error in POSIX.

POSIX also specifies that in case of underflow, arg is returned unmodified, and if that is not supported, an implementation-defined value no greater than DBL_MIN, FLT_MIN, and LDBL_MIN is returned.

Функция sin в C

Системный вызов Waitpid на C

Программирование и разработка

В математике функция синуса входит в число трех основных функций, другие включают косинус и тангенс. Методы выполнения основных математических операций, таких как элементарные экспоненциальные, логарифмические, квадратные и математические операции, включены в заголовок <math.h>. Вы должны включить файл заголовка <math.h>, чтобы использовать эти функции. Функция sin принимает угол в радианах и выдает его значение синуса, которое может быть подтверждено с помощью кривой синуса.

Вы можете использовать закон синуса, чтобы найти любой произвольный угол в треугольнике, а также длину определенной стороны треугольника. Это фундаментальное тригонометрическое понятие. Функция sin используется в версиях языка C. ANSI / ISO 9899-1990. Sin () возвращает результат от 1 до -1.

Теперь давайте начнем с нескольких примеров функции sin () на языке программирования C.

Предварительные условия

  • Установка компилятора GCC в Windows / Linux

Примечание: мы используем компилятор GCC в Windows 10.

Пример 1

В нашей первой иллюстрации мы собираемся использовать функцию sin () в нашей программе. Изначально вам нужно открыть компилятор GCC и создать новый файл с любым требуемым именем. После этого вставьте в него следующий код.

Мы добавили несколько библиотек

Мы добавили несколько библиотек: <stdio.h> и <math.h>. После добавления перейдите к основной функции. В функции main () мы объявили две переменные, «a» и «result» с типом данных double. Одной из переменных мы присвоили ей значение «7.1» и вычислили ее значение sin; вывод будет сохранен в переменной «результат». Затем мы присвоили отрицательное значение переменной «a» и вычислили ее значение sin. После этого переменной «а» будет присвоен ноль, и результат ее вычисления будет сохранен в переменной «результат». Теперь мы готовы к выполнению программы. В строке меню компилятора GCC вы должны нажать на опцию «Скомпилировать и запустить», чтобы получить результат. Эта опция присутствует в меню «Сборка».

После добавления перейдите к основной функции

Как только вы нажмете на эту опцию, на вашем экране появится черный экран с названием «Консоль». Вы получите следующий прикрепленный результат, как показано на скриншоте ниже.

Вы получите следующий прикрепленный результат, как показано на скриншоте

Пример 2

Во втором примере мы будем использовать функцию sin () в нашей программе немного сложнее. Изначально вам нужно открыть компилятор GCC и создать новый файл с любым требуемым именем. Также можно использовать предыдущий файл. После этого вставьте в него следующий код.

Во втором примере мы будем использовать функцию sin

Мы добавили несколько библиотек: <stdio.h> и <math.h>. Мы добавили значение PI, как видно на скриншоте. После добавления перейдите к основной функции. В функции main () мы объявили три переменные «a», «retu» и «value» с типом данных double. Одной из переменных мы присвоили ей значение «79.0». Мы применили формулу, сохранили ее значение в переменной «retu» и вычислили ее значение sin; затем мы распечатали результат с помощью функции printf (). Теперь мы готовы к выполнению программы. В строке меню компилятора GCC вы должны нажать на опцию «Скомпилировать и запустить», чтобы получить результат. Эта опция присутствует в меню «Сборка».

Как только вы нажмете на эту опцию, на вашем экране появится черный экран с названием «Консоль». Вы получите следующий прикрепленный результат, как показано на прилагаемом ниже снимке экрана.

Как только вы нажмете на эту опцию, на вашем экране появится черный экран

Пример 3

В нашем третьем и последнем примере мы будем использовать функцию sin () в нашей программе немного по-другому. Этот пользователь должен ввести число во время выполнения, чтобы вычислить значение sin (). Изначально вам нужно открыть компилятор GCC и создать новый файл с любым требуемым именем. Также можно использовать предыдущий файл. После этого вставьте в него следующий код.

В нашем третьем и последнем примере мы будем использовать функцию sin

Мы добавили несколько библиотек: <stdio.h> и <math.h>. После добавления перейдите к основной функции. В функции main () мы объявили две переменные «Sineval» и «num» с типом данных double. Мы использовали функции printf () и scanf (). После этого мы вычислим sin () введенного пользователем значения и отобразим его результат.

Теперь мы готовы выполнить программу. В строке меню компилятора GCC вы должны нажать на опцию «Скомпилировать и запустить», чтобы получить результат. Эта опция присутствует в меню «Сборка». Как только вы нажмете на эту опцию, на вашем экране появится черный экран с названием «Консоль». Вы получите следующий прикрепленный результат, как показано на скриншоте ниже.

В строке меню компилятора GCC вы должны нажать на опцию

Как видите, мы ввели число «19» и тоже получили его результат. Номер можно выбрать в соответствии с вашими потребностями.

Номер можно выбрать в соответствии с вашими потребностями

Заключение

Эта статья представляет собой краткое введение в функцию sin () в языке программирования C. Мы разработали три различных примера для понимания пользователями. Все примеры разные по реализации. Теперь я надеюсь, что всякий раз, когда вы пытаетесь реализовать эти примеры в своей системе, вы легко поймете основную концепцию функции sin () в языке программирования C.

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