# ANN: ChangePrecision.jl

**URL:** <https://discourse.julialang.org/t/ann-changeprecision-jl/6721>\
**Category:** Tooling\
**Tags:** package, announcement\
**Created:** [October 27, 2017, 2:10pm UTC](https://discourse.julialang.org/t/ann-changeprecision-jl/6721 "2017-10-27T14:10:45Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [October 27, 2017, 2:10pm UTC](https://discourse.julialang.org/t/ann-changeprecision-jl/6721/1 "2017-10-27T14:10:45Z")

</div>

[ChangePrecision.jl](https://github.com/stevengj/ChangePrecision.jl), which has been mentioned recently on a [couple](https://discourse.julialang.org/t/change-default-precision/6520/47) of [other](https://discourse.julialang.org/t/performing-arithmetic-operations-in-quadruple-precision/4265/14) threads, is now a registered package.

This package allows you to effectively change the “default” precision in a large body of Julia code, simply by doing e.g. `@changeprecision Float32 include("foo.jl")` or, for example:

```julia
using ChangePrecision
@changeprecision BigFloat begin
    x = pi/2
    y = 2.1 * x * rand(3,3) \ linspace(0,1,3)
end

```

and all floating-point literals, as well as many functions like `rand()` or expressions like `3/2` will now default to the new type (here `BigFloat`) rather than `Float64`. Code that uses explicit types, like `rand(Float64)`, will not be affected.

This is mainly meant for informal user “scripts” rather than library code, since library code should typically be written in a type-generic manner (inferring the desired precision from function arguments rather than hardcoding it).

---

<div class="post-metadata">

**Author:** ![avik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/avik/32/17_2.png) [@avik](https://discourse.julialang.org/u/avik)\
**Post date:** [October 27, 2017, 3:58pm UTC](https://discourse.julialang.org/t/ann-changeprecision-jl/6721/2 "2017-10-27T15:58:24Z")

</div>

For functions, should the definitions, or call point, or both be wrapped in the macro?

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [October 27, 2017, 5:49pm UTC](https://discourse.julialang.org/t/ann-changeprecision-jl/6721/3 "2017-10-27T17:49:48Z")

</div>

> [@avik](#):
>
> For functions, should the definitions, or call point, or both be wrapped in the macro?

The definitions.

As it says in the README, it doesn’t “look inside” functions that you call and rewrite them (there is no way for a macro to do this). The `@changeprecision` macro only transforms expressions that explicitly appear in the code you apply it to (or code inserted by `include`).

(The function calls that it transforms are only a specific set of `Base` functions that the macro knows about…and it’s not actually _changing_ those functions, just calling a different method of them.)

---

<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:** [October 27, 2017, 6:24pm UTC](https://discourse.julialang.org/t/ann-changeprecision-jl/6721/4 "2017-10-27T18:24:13Z")

</div>

Not to dismiss your work, but I am skeptical of the utility of packaging this (other than for demonstrating how powerful Julia is so that it allows you to do this). Having a registered package may just divert some inexperienced users from the right solution (writing generic code, yes, even for scripts).

---

<div class="post-metadata">

**Author:** ![jw3126](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jw3126/32/3086_2.png) [@jw3126](https://discourse.julialang.org/u/jw3126)\
**Post date:** [October 27, 2017, 7:16pm UTC](https://discourse.julialang.org/t/ann-changeprecision-jl/6721/5 "2017-10-27T19:16:01Z")

</div>

So you suggest to write e.g. `T(1.32)` everywhere in a quick and dirty script with lots of numeric constants? And add tests that make sure you did not forget a `T` somewhere?

(In my scripts I just write `1.32` and only add the `T` when I need it. `ChangePrecision` seems handy.)

OTOH sometimes I really want `Rational{BigInt}(132, 100)` instead of `1.32` and thats seems impossible with a macro.

---

<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:** [October 28, 2017, 7:32am UTC](https://discourse.julialang.org/t/ann-changeprecision-jl/6721/6 "2017-10-28T07:32:35Z")

</div>

> [@jw3126](#):
>
> you suggest to write e.g. T(1.32) everywhere in a quick and dirty script with lots of numeric constants?

It is hard to say without the code, but if you have _lots_ of numeric constants, you might want to use some container structure to organize them. See, for example, the implementation of [Base.Math.JuliaLibm.log1p](https://github.com/JuliaLang/julia/blob/master/base/special/log.jl#L1).

---

<div class="post-metadata">

**Author:** ![ascetic168](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ascetic168/32/7645_2.png) [@ascetic168](https://discourse.julialang.org/u/ascetic168)\
**Post date:** [March 18, 2019, 7:24am UTC](https://discourse.julialang.org/t/ann-changeprecision-jl/6721/7 "2019-03-18T07:24:57Z")

</div>

ChangePrecision.jl is a brilliant idea.

For some computational Physics applications, “high precision float” is necessary. I found BigFloat calculation is too slow, but DoubleFloats.jl works great on it.

So far, float constants are evaluated as Float64 values before additional processing.  
For example, I always use x=df64"2.1" instead of x=Double64(2.1)  
Between them, it exists an error of 8.88E-17.  
So, there are many “df64” string in my code, seems not good.

Is it possible to make ChangePrecision.jl support Double64 type? I will aprreciate it very much!

---

<div class="post-metadata">

**Author:** ![antoine-levitt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/antoine-levitt/32/4008_2.png) [@antoine-levitt](https://discourse.julialang.org/u/antoine-levitt)\
**Post date:** [March 18, 2019, 8:10am UTC](https://discourse.julialang.org/t/ann-changeprecision-jl/6721/8 "2019-03-18T08:10:51Z")

</div>

I don’t think it is possible, because literals are evaluated as Float64 before macros have any chance to do anything about them.

---

<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:** [March 18, 2019, 11:05am UTC](https://discourse.julialang.org/t/ann-changeprecision-jl/6721/9 "2019-03-18T11:05:41Z")

</div>

> [@ascetic168](#):
>
> Is it possible to make ChangePrecision.jl support Double64 type? I will aprreciate it very much!

That shouldn’t be more difficult than this (note: the `tryparse` implementation doesn’t handle errors correctly but is good enough for the purpose here):

```julia
julia> using ChangePrecision, DoubleFloats

julia> Base.tryparse(::Type{Double64}, s::AbstractString) = Double64(s)

julia> @changeprecision Double64 t = 2.1
2.1

julia> t == df64"2.1"
true

```

> [@antoine-levitt](#):
>
> I don’t think it is possible, because literals are evaluated as Float64 before macros have any chance to do anything about them.

Actually it can, by converting the literal back to a string and parsing it again for the new precision.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [March 18, 2019, 12:24pm UTC](https://discourse.julialang.org/t/ann-changeprecision-jl/6721/10 "2019-03-18T12:24:50Z")

</div>

> [@GunnarFarneback](#):
>
> That shouldn’t be more difficult than this (note: the `tryparse` implementation doesn’t handle errors correctly but is good enough for the purpose here):

Right, as long as the type supports `parse` (which seems temporarily missing for DoubleFloat: [missing parse/tryparse · Issue #64 · JuliaMath/DoubleFloats.jl · GitHub](https://github.com/JuliaMath/DoubleFloats.jl/issues/64)), then ChangePrecision will work.

Floating-point literals like `2.1` are handled by converting back to string and re-parsing. This works because even though `2.1` is initially parsed as `Float64`, the [grisu algorithm](https://github.com/kring/grisu.net) that is used for printing floats outputs the _shortest_ possible representation, so it will print `2.1` rather than `2.10000000000000008881784…`. It’s not perfect in theory, because if you actually do enter `2.10000000000000008881784` as a literal constant, then it will get converted to `2.1`, but this doesn’t seem to be a problem in practice — floating-point literals with 15+ digits are essentially never exact values.

---

<div class="post-metadata">

**Author:** ![ascetic168](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ascetic168/32/7645_2.png) [@ascetic168](https://discourse.julialang.org/u/ascetic168)\
**Post date:** [March 27, 2019, 11:00am UTC](https://discourse.julialang.org/t/ann-changeprecision-jl/6721/11 "2019-03-27T11:00:55Z")

</div>

> [@GunnarFarneback](#):
>
> @changeprecision Double64

Thanks, It helps!  
Only one more thing, “tryparse” seems can handle more than 15+ digits. For example:

x=tryparse(BigFloat,“0.123456789876543212345678987654321”)  
y=Double64(x)  
z=tryparse(Double64,“0.123456789876543212345678987654321”)

y or z is printed as “0.12345678987654321”  
but x-y or x-z approach to 7.9E-35

---

<div class="post-metadata">

**Author:** ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)\
**Post date:** [March 27, 2019, 11:25am UTC](https://discourse.julialang.org/t/ann-changeprecision-jl/6721/12 "2019-03-27T11:25:49Z")

</div>

`DoubleFloats.jl` now does implement `tryparse`.  
`Double64s` print only the higher order part of their value by default. You can see all of it in [a few ways](https://juliamath.github.io/DoubleFloats.jl/stable/stringshowparse/).
