Percent written as x%

macro %(x)
    Unitful.percent(.01x) 
end

@% 12   #12 %

Is there a function or macro that would allow 12% instead of @% 12

No, because % is parsed as a binary operator (by default defined as a synonym for rem). Functions and macros can’t change how things are parsed, only what they do.

You could define

struct PCT; end
const pct = PCT()
Base.:*(x, ::PCT) = Unitful.percent(x/100)

which would allow you to do e.g.

julia> 12pct
12.0 %
13 Likes

While I’d probably recommend @stevengj’s approach, you could do the following if you really like the % symbol:

# define our own local shadow of %
(%)(args...) = Base.:(%)(args...)
Base.:(*)(x, ::typeof(%)) = Unitful.percent(x/100)

and then you can write

julia> 12.0(%)
12.0 %

and

julia> let y = 12.0
           y*(%)
       end
12.0 %

Just another fun option.

4 Likes

I often export the units directly (frequently with using Unitful.DefaultSymbols):

julia> using Unitful: percent

julia> 25percent
25 %

julia> 25percent |> NoUnits
1//4
6 Likes

You can also abuse unicode if you want this to be write-once:

julia> using Unitful: percent as ᵒ╱ₒ

julia> 25ᵒ╱ₒ
25 %
6 Likes
using Unitful: percent          as pc
using Unitful: pertenthousand   as bp

Percent    = typeof(1pc)
BasisPoint = typeof(1bp)

struct mystruct
    rate::Percent
    spread::BasisPoint
end

mystruct(4pc, 12bp)

This is great!
Though it wont allow 4.5pc.
Steve’s longer approach allowed for this.

1 Like

It’s allowed:

julia> 4.5pc
4.5 %

Except in your context (but likely fixable):

I.e. that seemsed intentional, only allowing integers there:

julia> mystruct(4.5pc, 12bp)
ERROR: InexactError: Int64(4.5)

I see it now, did you mean for:

julia> Percent    = typeof(1.0pc)
Unitful.Quantity{Float64, NoDims, Unitful.FreeUnits{(%,), NoDims, nothing}}

julia> 4.5pc
4.5 %

julia> typeof(ans)
Unitful.Quantity{Float64, NoDims, Unitful.FreeUnits{(%,), NoDims, nothing}}

julia> 4pc
4 %

julia> typeof(ans)  # beware not same:
Unitful.Quantity{Int64, NoDims, Unitful.FreeUnits{(%,), NoDims, nothing}}

There’s probably some easy way(?) to allow the latter, meaning to convert to the former type if that’s what you want (or stored as an integer scaled by 10, though a bit more work… yet more option is a decimal type…).

1 Like

thank you. that works.

Percent    = typeof(1.0pc)