# Performing arithmetic operations in quadruple precision

**URL:** <https://discourse.julialang.org/t/performing-arithmetic-operations-in-quadruple-precision/4265>\
**Category:** General Usage\
**Created:** [June 14, 2017, 9:46am UTC](https://discourse.julialang.org/t/performing-arithmetic-operations-in-quadruple-precision/4265 "2017-06-14T09:46:30Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![michakraus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/michakraus/32/222105_2.png) [@michakraus](https://discourse.julialang.org/u/michakraus)\
**Post date:** [June 14, 2017, 9:46am UTC](https://discourse.julialang.org/t/performing-arithmetic-operations-in-quadruple-precision/4265/1 "2017-06-14T09:46:30Z")

</div>

I need to compute simple arithmetic expressions with +,-,\*,/,√ in quadruple precision using DecFP where the various coefficients are hard-coded. In order to get an accurate result, all numbers have to be converted to DecFP128 before applying any operators. In the code that would look like

> `Dec128(5)/Dec128(36)-Dec128(7)*√Dec128(15)/Dec128(30)`

which, quite obviously, gives a different result as

> `Dec128(5/36-7*√15/30)`

Is there a more compact way of doing this?

If it weren’t for √ rationals would be a solution, but I need roots…

---

<div class="post-metadata">

**Author:** ![piever](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/piever/32/1815_2.png) [@piever](https://discourse.julialang.org/u/piever)\
**Post date:** [June 14, 2017, 11:36am UTC](https://discourse.julialang.org/t/performing-arithmetic-operations-in-quadruple-precision/4265/2 "2017-06-14T11:36:48Z")

</div>

I’m completely unfamiliar with the package but I guess you could do a macro that replaces all integers that it founds with the correspondent DecFP128. For example

```julia
function _dec128(x::Expr)
    y = x
    y.args .= _dec128.(y.args)
    return y
end

_dec128(x::Int) = Dec128(x)

_dec128(x) = x

macro dec128(x)
    return esc(_dec128(x))
end

```

Now you can just d:

```julia
julia> @dec128 5/36-7*√15/30
-7648072252261750509862730377270044E-34

julia> ans == Dec128(5)/Dec128(36)-Dec128(7)*√Dec128(15)/Dec128(30)
true

```

---

<div class="post-metadata">

**Author:** ![michakraus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/michakraus/32/222105_2.png) [@michakraus](https://discourse.julialang.org/u/michakraus)\
**Post date:** [June 14, 2017, 11:58am UTC](https://discourse.julialang.org/t/performing-arithmetic-operations-in-quadruple-precision/4265/3 "2017-06-14T11:58:25Z")

</div>

Thanks a lot for the quick reply! I was under the impression that a macro like that would be the solution. I just wasn’t sure how exactly that should look like…

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [June 14, 2017, 12:32pm UTC](https://discourse.julialang.org/t/performing-arithmetic-operations-in-quadruple-precision/4265/5 "2017-06-14T12:32:55Z")

</div>

Please don’t use `convert` for this.

---

<div class="post-metadata">

**Author:** ![shorty66](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shorty66/32/3254_2.png) [@shorty66](https://discourse.julialang.org/u/shorty66)\
**Post date:** [June 14, 2017, 1:14pm UTC](https://discourse.julialang.org/t/performing-arithmetic-operations-in-quadruple-precision/4265/6 "2017-06-14T13:14:31Z")

</div>

Okay, i changed the name and got the macro working.  
How would i get rid of the `eval` in the macro?

```julia
module ConvertArguments

export @convertarguments

function convertarguments(T, ex::Expr)
   for (i, arg) in enumerate(ex.args)
       if typeof(arg) <: Number
           ex.args[i] = Expr(:call, :convert, T, arg)
       elseif typeof(arg) == Expr
           ex.args[i] = convertarguments(T, arg)
       end
   end
   return :($ex)
end

macro convertarguments(T,ex)
    return convertarguments(T,ex)
end

end #module ConvertArguments

```

```julia
julia> include("ConvertArguments.jl"); using ConvertArguments

julia> @macroexpand @convertarguments BigInt 1+3/4.0*√6
:((ConvertArguments.convert)(ConvertArguments.BigInt, 1) + ((ConvertArguments.convert)(ConvertArguments.BigInt, 3) / (ConvertArguments.convert)(ConvertArguments.BigInt, 4.0)) * √((ConvertArguments.convert)(ConvertArguments.BigInt, 6)))

julia> @convertarguments BigInt 1+3/4.0*√6
2.837117307087383573647963056029418543974460610492502596324519425438220283092974

```

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [June 14, 2017, 1:20pm UTC](https://discourse.julialang.org/t/performing-arithmetic-operations-in-quadruple-precision/4265/7 "2017-06-14T13:20:41Z")

</div>

A macro should return an expression. That expression will be eval’ed when the macro is called.

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [June 14, 2017, 1:21pm UTC](https://discourse.julialang.org/t/performing-arithmetic-operations-in-quadruple-precision/4265/8 "2017-06-14T13:21:45Z")

</div>

So you should pass the symbol T through to the function, and build up an expression that converts things to the type given by the symbol T.

---

<div class="post-metadata">

**Author:** ![shorty66](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shorty66/32/3254_2.png) [@shorty66](https://discourse.julialang.org/u/shorty66)\
**Post date:** [June 14, 2017, 1:49pm UTC](https://discourse.julialang.org/t/performing-arithmetic-operations-in-quadruple-precision/4265/9 "2017-06-14T13:49:58Z")

</div>

I edited my first post to reflect your suggestions. Would that by the ideomatic way to do it?

---

<div class="post-metadata">

**Author:** ![dpo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpo/32/3335_2.png) [@dpo](https://discourse.julialang.org/u/dpo)\
**Post date:** [June 14, 2017, 3:33pm UTC](https://discourse.julialang.org/t/performing-arithmetic-operations-in-quadruple-precision/4265/10 "2017-06-14T15:33:31Z")

</div>

Could you please explain why `convert` is not a good idea here?

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [June 14, 2017, 3:38pm UTC](https://discourse.julialang.org/t/performing-arithmetic-operations-in-quadruple-precision/4265/11 "2017-06-14T15:38:39Z")

</div>

Well, it’s by no mean a convertion…

1. It doesn’t return a type it is converting to
2. It’ll cause assignment of `Expr` object to a typed slot to raise a strange error.
3. It’s probably also a type piracy though that’s much less of a concern…

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [June 14, 2017, 3:42pm UTC](https://discourse.julialang.org/t/performing-arithmetic-operations-in-quadruple-precision/4265/12 "2017-06-14T15:42:15Z")

</div>

- This does not handle escape correctly. You must escape all arguments ones and exactly ones.

- I’m not sure what’s the best way to handle this but you can accidentally handle some `Expr`s that you don’t want to handle (line numbers for example…)

- There’s also `isa` which you should use instead of `typeof`

- And `:($ex)` is a no-op.

---

<div class="post-metadata">

**Author:** ![greg\_plowman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/greg_plowman/32/8100_2.png) [@greg\_plowman](https://discourse.julialang.org/u/greg_plowman)\
**Post date:** [June 15, 2017, 2:54am UTC](https://discourse.julialang.org/t/performing-arithmetic-operations-in-quadruple-precision/4265/13 "2017-06-15T02:54:44Z")

</div>

Note that simple binary operators (+,-,\*,/) should promote automatically, so in your case, you only need to explicitly use `Dec128` for √.

```julia
Julia-0.5.1> x1 = Dec128(5)/Dec128(36)-Dec128(7)*√Dec128(15)/Dec128(30)
-7648072252261750509862730377270044E-34

Julia-0.5.1> x2 = Dec128(5)/36-7*√Dec128(15)/30
-7648072252261750509862730377270044E-34

Julia-0.5.1> x1 == x2
true

```

Also note that `DoubleDouble` also seems to support the operations you need and could be faster:

```julia
Julia-0.5.1> y1 = Double(5)/Double(36)-Double(7)*√Double(15)/Double(30)
Double(-0.7648072252261751, 7.110782587967322e-18)
 - value: -0.76480722522617505098627303772702

Julia-0.5.1> y2 = Double(5)/36-7*√Double(15)/30
Double(-0.7648072252261751, 7.110782587967322e-18)
 - value: -0.76480722522617505098627303772702

Julia-0.5.1> y1 == y2
true

```

```julia
Julia-0.5.1> @btime Dec128(5)/36-7*√Dec128(15)/30
  443.050 ns (0 allocations: 0 bytes)
-7648072252261750509862730377270044E-34

Julia-0.5.1> @btime Double(5)/36-7*√Double(15)/30
  84.492 ns (0 allocations: 0 bytes)
Double(-0.7648072252261751, 7.110782587967322e-18)
 - value: -0.76480722522617505098627303772702

```

---

<div class="post-metadata">

**Author:** ![greg\_plowman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/greg_plowman/32/8100_2.png) [@greg\_plowman](https://discourse.julialang.org/u/greg_plowman)\
**Post date:** [October 25, 2017, 8:40pm UTC](https://discourse.julialang.org/t/performing-arithmetic-operations-in-quadruple-precision/4265/14 "2017-10-25T20:40:17Z")

</div>

Also see this: [Change default precision - #47 by stevengj](https://discourse.julialang.org/t/change-default-precision/6520/47)

```julia
using DecFP
using ChangePrecision

y = Dec128(5)/Dec128(36)-Dec128(7)*√Dec128(15)/Dec128(30)

@changeprecision Dec128 begin
    z = 5/36 - 7*√15/30
end

y == z # true

```

EDIT: or more concisely:

```julia
@changeprecision Dec128 z = 5/36-7*√15/30

```
