Open boriskaus opened 2 years ago
The powers are not just converted to Rational
for display, they are actually stored as Rational
s in the type of the unit. One could write a function to print unit powers as decimals instead of fractions, but this wouldn’t change the underlying behavior. If display is all that you are concerned with, this may be an option.
If you actually require numbers that cannot be represented as Rational{Int}
, different printing wouldn’t help much. The power of a unit is hardcoded to Rational{Int}
here. You could try to change this to Float64
(you might have to change some other code too if this breaks things, I’m not sure) and see whether it works for you.
Keep in mind that every unit^power
has its own type, so if you do a lot of arithmetic involving different powers, things might get slow (julia will have to compile new code for every new power).
thanks! Display is indeed all I am concerned with. How can I best replace/overload the current printing option?
The printing can be changed by replacing Unitful.superscript
. You can either replace the implementation here or add a specialized method to your own code:
Unitful.superscript(i::Rational{Int64}; io=nothing) = "^"*string(float(i))
thanks for the suggestion! I have now added this in our package, which works as expected.
function Unitful.superscript(i::Rational{Int64}; io=nothing)
string(superscript(float(i)))
if io === nothing
iocontext_value = nothing
else
iocontext_value = get(io, :fancy_exponent, nothing)
end
if iocontext_value isa Bool
fancy_exponent = iocontext_value
else
v = get(ENV, "UNITFUL_FANCY_EXPONENTS", Sys.isapple() ? "true" : "false")
t = tryparse(Bool, lowercase(v))
fancy_exponent = (t === nothing) ? false : t
end
if fancy_exponent
return superscript(float(i))
else
return "^" * string(float(i))
end
end
Unitful.superscript(i::Float64) = map(repr(i)) do c
c == '-' ? '\u207b' :
c == '1' ? '\u00b9' :
c == '2' ? '\u00b2' :
c == '3' ? '\u00b3' :
c == '4' ? '\u2074' :
c == '5' ? '\u2075' :
c == '6' ? '\u2076' :
c == '7' ? '\u2077' :
c == '8' ? '\u2078' :
c == '9' ? '\u2079' :
c == '0' ? '\u2070' :
c == '.' ? '\u0387' :
error("unexpected character")
end
Note that this superscript(::Float64)
does not work for all values (try 1.0e6
). There is also an unnecessary string(superscript(float(i)))
in the superscript(::Rational{Int64}; io)
method.
We could also think about incorporating something like this into Unitful
to avoid the type piracy and invalidations, therefore I am reopening it.
Thanks for this great package! In general it seems that Unitful transfers the powers of units to
Rational
numbers before displaying:or, on a Mac:
This works well if the powers are simple. Yet, in my research field we often have powers that are not easily transferrable to rational numbers, such as
In these cases it would probably be better to display the units as
Float64
rather than asRational
numbers, such asWould such an option be difficult to implement?