# Problem with sign(pi)

**URL:** <https://discourse.julialang.org/t/problem-with-sign-pi/47801>\
**Category:** General Usage\
**Tags:** bug\
**Created:** [October 5, 2020, 4:37pm UTC](https://discourse.julialang.org/t/problem-with-sign-pi/47801 "2020-10-05T16:37:48Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![aml](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aml/32/202471_2.png) [@aml](https://discourse.julialang.org/u/aml)\
**Post date:** [October 5, 2020, 4:37pm UTC](https://discourse.julialang.org/t/problem-with-sign-pi/47801/1 "2020-10-05T16:37:48Z")

</div>

The following behavior seems strange:

```julia
sign(pi)
ERROR: InexactError: Bool(-1)
Stacktrace:
 [1] Bool at .\float.jl:73 [inlined]
 [2] convert at .\number.jl:7 [inlined]
 [3] oftype(::Bool, ::Int64) at .\essentials.jl:367
 [4] sign(::Irrational{:π}) at .\number.jl:118
 [5] top-level scope at none:1

```

I’m I doing something wrong?

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [October 5, 2020, 4:46pm UTC](https://discourse.julialang.org/t/problem-with-sign-pi/47801/2 "2020-10-05T16:46:11Z")

</div>

No, this seems like a bug. The problematic definition is:

```julia
sign(x::Real) = ifelse(x < zero(x), oftype(one(x),-1), ifelse(x > zero(x), one(x), typeof(one(x))(x)))

```

But we have:

```julia
julia> one(pi)
true

```

so the `sign` function is trying to convert `-1` to a `Bool`. I’m not sure why `one(pi)` is a bool anyway, but it appears to be intentional.

I would suggest filing an issue at [Issues · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues)

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [October 5, 2020, 6:40pm UTC](https://discourse.julialang.org/t/problem-with-sign-pi/47801/3 "2020-10-05T18:40:31Z")

</div>

> [@rdeits](#):
>
> I’m not sure why `one(pi)` is a bool anyway, but it appears to be intentional.

I assume it’s so that calculations including pi do not promote results more than required. Bool is the “smallest” number type. This is also why `I(2)` turns into a matrix of bools if you call Matrix on it.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [October 5, 2020, 6:51pm UTC](https://discourse.julialang.org/t/problem-with-sign-pi/47801/4 "2020-10-05T18:51:26Z")

</div>

That makes sense. In that case, `one(pi)` seems fine but `sign()` should probably have an extra method for `::AbstractIrrational` to handle the fact that `one(x)` will not be large enough to hold -1.

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [October 5, 2020, 7:15pm UTC](https://discourse.julialang.org/t/problem-with-sign-pi/47801/5 "2020-10-05T19:15:00Z")

</div>

this Bool matrix also looks awkward… maybe we should just use `Int8` to be the “smallest” number type. I think Bool is stored with 1 byte anyways at the end of the day?

```julia
julia> sizeof(Int8(-1))
1

julia> sizeof(true)
1

```

---

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [October 5, 2020, 7:23pm UTC](https://discourse.julialang.org/t/problem-with-sign-pi/47801/6 "2020-10-05T19:23:01Z")

</div>

It’s not about the storage `true` requires to store, it’s mostly because usually `promote(::Bool, ::T)::T`, i.e. `Bool` is kind of the “neutral type” under promotion.

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [October 5, 2020, 7:25pm UTC](https://discourse.julialang.org/t/problem-with-sign-pi/47801/7 "2020-10-05T19:25:06Z")

</div>

[https://github.com/JuliaLang/julia/blob/ff20ff072b1141ed0504956d15718a7e0176a218/base/irrationals.jl#L151-L154](https://github.com/JuliaLang/julia/blob/ff20ff072b1141ed0504956d15718a7e0176a218/base/irrationals.jl#L151-L154)

based on L154, maybe we should make the previous two `1.0` instead. Or at least `1`. Breaking ☹

nvm, bad idea, since `zero` goes to `false`, this probably can’t be touched.

* * *

maybe this in the `sign(x::Real)` definition, instead:

```julia
julia> -one(pi)
-1

julia> oftype(one(pi),-1)
ERROR: InexactError: Bool(-1)

```

---

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [October 5, 2020, 7:25pm UTC](https://discourse.julialang.org/t/problem-with-sign-pi/47801/8 "2020-10-05T19:25:25Z")

</div>

The solution here is probably to use `one(signed(x))` instead of `one(x)` if `x::Unsigned`.

---

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [October 5, 2020, 7:32pm UTC](https://discourse.julialang.org/t/problem-with-sign-pi/47801/9 "2020-10-05T19:32:30Z")

</div>

The idea behind `AbstractIrrational` is that the irrational constants can take on the type of the other numbers used in a calculation, so e.g. `pi + 1.0` gives a `Float64`, `pi + big"1.0"` a `BigFloat`, `pi + 1f0` a `Float32`, etc. Returning a `Float64` in `one(::AbstractIrrational)` would defeat this, because it would convert any `Float32` you add it to (or do any other arithmetic operation with) to a `Float64` instead.
