*[Numeric functions](../perlfunc-by-category.md)*
# sin
Return the sine of a number given in radians.
`sin` is the standard trigonometric sine: it takes an angle measured
in **radians** and returns the ratio of the opposite side to the
hypotenuse of the corresponding right triangle. If `EXPR` is omitted,
`sin` operates on [`$_`](../perlvar.md). The result is always a
floating-point number in the closed interval `[-1, 1]`.
## Synopsis
```perl
sin EXPR
sin
```
## What you get back
A double-precision float in `[-1, 1]`. Perl forwards the call to the
platform’s C `sin(3)` routine, so the precision and rounding
behaviour match your libm. Special values follow IEEE 754: `sin(0)`
is exactly `0`, `sin("inf")` and `sin("nan")` are both `NaN`.
## Radians, not degrees
The single most common mistake with `sin` is feeding it degrees. A
full turn is `2 * π` radians, not `360`. Convert once and keep the
converted value:
```perl
use POSIX qw(acos);
my $pi = acos(-1); # π to full double precision
sub deg2rad { $_[0] * $pi / 180 }
print sin( deg2rad(30) ), "\n"; # 0.5
print sin( 30 ), "\n"; # -0.988031624092862 — wrong if you meant degrees
```
Math::Trigext exports `deg2rad` and `rad2deg` if you would rather not
write the conversion yourself.
## Examples
`sin(π/2)` is mathematically exactly `1`, but because `π` is not
representable in binary floating-point the computed result falls a
few ulps short:
```perl
use POSIX qw(acos);
my $pi = acos(-1);
printf "%.17f\n", sin($pi / 2); # 1.00000000000000000
printf "%.17f\n", sin($pi); # 0.00000000000000012 — not exactly 0
```
Treat any ”should be zero“ trig result as approximately zero. Compare
with a tolerance, not with `==`.
Degree-to-radian conversion inline, without pulling in a module.
`3.14159` is accurate to six digits — fine for plotting, not for
numeric analysis:
```perl
for my $deg (0, 30, 45, 60, 90) {
printf "sin(%2d°) = %+.4f\n",
$deg, sin($deg * 3.14159 / 180);
}
# sin( 0°) = +0.0000
# sin(30°) = +0.5000
# sin(45°) = +0.7071
# sin(60°) = +0.8660
# sin(90°) = +1.0000
```
For work that needs full double precision, replace `3.14159` with
`acos(-1)` or `atan2(1, 1) * 4`.
Numerical derivative of `sin` by finite differences. The symmetric
two-point formula `(f(x+h) - f(x-h)) / (2h)` should recover `cos(x)`:
```perl
my $x = 1.0;
my $h = 1e-6;
my $deriv = (sin($x + $h) - sin($x - $h)) / (2 * $h);
printf "derivative: %.10f\n", $deriv; # 0.5403023059
printf "cos(%.1f): %.10f\n", $x, cos($x);
```
Picking `$h` is a trade-off: too large and truncation error
dominates, too small and subtraction cancellation destroys the
result. `1e-6` is a reasonable default for double precision.
Walk the unit circle and print `(cos θ, sin θ)` at eight evenly
spaced angles:
```perl
use POSIX qw(acos);
my $pi = acos(-1);
for my $k (0 .. 7) {
my $theta = $k * $pi / 4;
printf "%.3f %+.3f %+.3f\n",
$theta, cos($theta), sin($theta);
}
```
Inverse sine (arcsine) via the identity from `perlfunc`:
```perl
sub asin { atan2( $_[0], sqrt(1 - $_[0] * $_[0]) ) }
print asin(0.5), "\n"; # 0.523598775598299 (= π/6)
```
## Edge cases
- **Non-numeric arguments coerce to `0`**. `sin("hello")` returns
`0` because the string is numified to `0` first. Under
`use warnings` this produces an
`Argument "hello" isn't numeric in sin` warning. Validate input
with `looks_like_number` from `Scalar::Util` if the source is
untrusted.
- **Very large arguments lose precision**. `sin` first reduces its
argument modulo `2π`, and for `|x|` on the order of `1e16` the
nearest representable double differs from `x` by more than `π`.
The result is still a number in `[-1, 1]`, but it is essentially
random. Reduce the angle yourself before the call if you are
accumulating a phase over many iterations.
- **[`undef`](undef.md) coerces to `0`** and returns `0`, with the usual
`uninitialized` warning under `use warnings`.
- **IEEE specials**: `sin("inf")`, `sin("-inf")`, and `sin("nan")`
all return `NaN`. Compare with `$result != $result` (the only
value not equal to itself) to detect `NaN`, or use
`POSIX::isnan`.
- **Default argument**. `sin;` with no argument reads [`$_`](../perlvar.md). Inside
a `while (<>)` loop this operates on the current line, which is
almost always a bug.
- **No complex-number support** in the built-in. For complex
arguments use Math::Complexext, which overloads `sin` via operator
overloading:
```perl
use Math::Complex;
my $z = cplx(1, 2);
print sin($z), "\n"; # 3.16577851321617+1.9596010414216i
```
## Differences from upstream
Fully compatible with upstream Perl 5.42.
## See also
- [`cos`](cos.md) — cosine of an angle in radians; the companion
function most often used alongside `sin`
- [`atan2`](atan2.md) — two-argument arctangent, the usual building
block for inverse trig (`asin`, `acos`) in pure Perl
- [`sqrt`](sqrt.md) — square root; appears in the classical `asin`
identity `asin(x) = atan2(x, sqrt(1 - x*x))`
- Math::Trigext — `asin`, `acos`, `atan`, hyperbolic variants,
`deg2rad`/`rad2deg`, and great-circle helpers
- Math::Complexext — overloads `sin` (and the rest of the trig
family) for complex arguments
- `POSIX` — exposes `asin` directly, plus `isnan`/`isinf` for
detecting the non-finite results discussed above