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!)