El viernes, 10 de octubre de 2014 05:15:48 UTC-5, Simon Byrne escribió:
>
>
>
> On Friday, 10 October 2014 04:12:37 UTC+1, David P. Sanders wrote:
>>
>> I believe (but please correct me if I'm wrong) that I do need a macro,
>> since I use it with whole expressions to ensure the correct rounding, for
>> example
>> (simplifying) something like
>>
>> @round_down( min(a*b, c*d) )
>>
>
> You can use with_rounding for this:
>
> with_rounding(() -> min(a*b,c*d), T, RoundDown)
>
> or equivalently, with do syntax:
>
> with_rounding(T, RoundDown) do
> min(a*b,c*d)
> end
>
Thanks. I should have been more clear.
I was previously using with_rounding, but in order to avoid this being
littered through the code, I wanted to hide it somewhere,
and this somewhere thus has to be a macro, in order to avoid the arithmetic
being performed before the function was even called:
macro round_down(expr)quote
with_rounding(BigFloat, RoundDown) do $expr end endend
(Not sure what happened to the indentation when copying from GitHub, sorry.)
This works great when everything is BigFloats.
But now I want to add the possibility that intervals store either Float64s
or BigFloats, so I wanted the
macro to also check the type of its argument, which is where my original
code came from.
One solution would be to add an explicit parameter T to the @round_down
macro, e.g. the following
which avoids eval at the expense of a repetitive code smell:
macro new_round_down(expr, T)
if T == :Float64
quote
with_rounding(Float64, RoundDown) do
$expr
end
end
elseif T == :BigFloat
quote
with_rounding(BigFloat, RoundDown) do
$expr
end
end
end
end
But this again makes the code more messy, since the Interval type must now
be parametrised (which may be a good idea anyway!)