# Cos(pi/2) does not return 0

**URL:** https://discourse.julialang.org/t/cos-pi-2-does-not-return-0/27081
**Category:** General Usage
**Created:** [August 1, 2019, 4:22pm UTC](https://discourse.julialang.org/t/cos-pi-2-does-not-return-0/27081 "2019-08-01T16:22:40Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![fhagemann](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fhagemann/32/9600_2.png) [@fhagemann](https://discourse.julialang.org/u/fhagemann)
#### Post date: [August 1, 2019, 4:22pm UTC](https://discourse.julialang.org/t/cos-pi-2-does-not-return-0/27081/1 "2019-08-01T16:22:40Z")

</div>

Hi!  
While trying out some stuff in Julia, I came across the fact that cos(pi/2) does not give exact 0, but some type dependent output (6e-17 for Float64, -4e-8 for Float32, 5e-4 for Float16). Is this intended? And what is the best way to avoid this?

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [August 1, 2019, 4:35pm UTC](https://discourse.julialang.org/t/cos-pi-2-does-not-return-0/27081/2 "2019-08-01T16:35:25Z")

</div>

Not intended, but hard to avoid because of floating point error. See

> [@PSA: floating-point arithmetic](https://discourse.julialang.org/t/psa-floating-point-arithmetic/8678):
>
> Sometimes people are surprised by the results of floating-point calculations such as julia\> 5/6 0.8333333333333334 # shouldn't the last digit be 3? julia\> 2.6 - 0.7 - 1.9 2.220446049250313e-16 # shouldn't the answer be 0? These are not bugs in Julia. They’re consequences of the IEEE-standard 64-bit binary representation of floating-point numbers that is burned into computer hardware, which Julia and many other languages use by default. Brief explanation You can t…

You can use

```julia
julia> cospi(0.5)
0.0

```

---

<div class="post-metadata">

### Author: ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)
#### Post date: [August 1, 2019, 5:33pm UTC](https://discourse.julialang.org/t/cos-pi-2-does-not-return-0/27081/3 "2019-08-01T17:33:00Z")

</div>

If what you are wondering is why Julia does not know the cosine involving the `Irrational` object `π` exactly, this is because it is converted to a float when performing the operation `π/2`. Base Julia does not implement `AffineFunctionOfIrrational` or anything like that. Someone might have done so in a package.

---

<div class="post-metadata">

### Author: ![chakravala](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chakravala/32/6832_2.png) [@chakravala](https://discourse.julialang.org/u/chakravala)
#### Post date: [August 1, 2019, 5:55pm UTC](https://discourse.julialang.org/t/cos-pi-2-does-not-return-0/27081/4 "2019-08-01T17:55:14Z")

</div>

> [@ExpandingMan](#):
>
> Julia does not know the cosine involving the `Irrational` object `π` exactly, this is because it is converted to a float when performing the operation `π/2`

Something similar to `UniformScaling` for irrationals could maybe help fix that issue.

> [@ExpandingMan](#):
>
> Base Julia does not implement `AffineFunctionOfIrrational` or anything like that. Someone might have done so in a package.

> **[GitHub - perrutquist/IrrationalExpressions.jl: Make expressions like 2π...](https://github.com/perrutquist/IrrationalExpressions.jl)**
>
> Make expressions like 2π behave as irrational numbers in Julia - GitHub - perrutquist/IrrationalExpressions.jl: Make expressions like 2π behave as irrational numbers in Julia

---

<div class="post-metadata">

### Author: ![fhagemann](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fhagemann/32/9600_2.png) [@fhagemann](https://discourse.julialang.org/u/fhagemann)
#### Post date: [August 1, 2019, 6:02pm UTC](https://discourse.julialang.org/t/cos-pi-2-does-not-return-0/27081/5 "2019-08-01T18:02:29Z")

</div>

I see, thanks so much for your responses!

I’m stuck with one more question though, but that might be because I’m starting out with Julia:  
I’ve had a look in the source code at `/opt/julia/share/julia/base/special/trig.jl `

```julia
function cos(x::T) where T<:Union{Float32, Float64}
    absx = abs(x)
    if absx < T(pi)/4
        if absx < sqrt(eps(T)/T(2.0))
            return T(1.0)
        end
        return cos_kernel(x)
    elseif isnan(x)
        return T(NaN)
    elseif isinf(x)
        cos_domain_error(x)
    else
        n, y = rem_pio2_kernel(x)
        n = n&3
        if n == 0
            return cos_kernel(y)
        elseif n == 1
            return -sin_kernel(y)
        elseif n == 2
            return -cos_kernel(y)
        else
            return sin_kernel(y)
        end
    end
end

```

that is apparently using approximations for cos(x), -sin(x), -cos(x) or sin(x) depending on the interval x is in.  
(I must admit I haven’t had a closer look at the `rem_pio2_kernel` function, but I admit that it returns the div and rem value from the division by π/2)

I defined my own function based on the same idea of evaluating the trigonometric functions only in the interval [-π/4, π/4] around either their extremum (cosine) or root (sine) as suggested by `cos_kernel`

```julia
function mycos(x)
  if x < 0
    return mycos(-x)
  else
    j = div(x+pi/4,pi/2)%4
    newx = x%2pi - j*pi/2
    if j == 0 return cos(newx)
    elseif j == 1 return -sin(newx)
    elseif j == 2 return -cos(newx)
    elseif j == 3 return sin(newx)
    end
    #if that should (in whatever case) not work, return normal value
    return cos(x)
  end
end

```

This does return the values at multiple of π/2 correctly (not talking about performance here). I don’t see too may differences to the function in `trig.jl` and wonder why that one is not capable of doing that…

---

<div class="post-metadata">

### Author: ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)
#### Post date: [August 1, 2019, 9:08pm UTC](https://discourse.julialang.org/t/cos-pi-2-does-not-return-0/27081/6 "2019-08-01T21:08:25Z")

</div>

> [@fhagemann](#):
>
> This does return the values at multiple of π/2 correctly (not talking about performance here). I don’t see too may differences to the function in `trig.jl` and wonder why that one is not capable of doing that…

Probably because it’s not in fact correct (e.g. the cosine of the closest Float64 representation of `pi/2` is not zero) and you get worse results everywhere. For example

```julia
julia> x = 1.571
1.571

julia> y1 = mycos(x)
-0.00020367320369523912

julia> y2 = cos(x)
-0.00020367320369517786

julia> y3 = cos(BigFloat(x))
-2.036732036951778709106180717800557926547406375863370495134343067126837115362263e-04

julia> abs(y1 - y3)
6.124442755166129148251053819710905768303105297194328731628846377367955634449768e-17

julia> abs(y2 - y3)
1.299519376970903891054505204264901252558765305671268371153622632044365550231594e-20

```

If you are specifically concerned about the cosine of multiples of pi, use the `cospi` function. It’s there for exactly that purpose.

---

<div class="post-metadata">

### Author: ![fhagemann](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fhagemann/32/9600_2.png) [@fhagemann](https://discourse.julialang.org/u/fhagemann)
#### Post date: [August 1, 2019, 10:15pm UTC](https://discourse.julialang.org/t/cos-pi-2-does-not-return-0/27081/7 "2019-08-01T22:15:33Z")

</div>

Alright! Thanks for your answer.
