Is there a generic way to remove the unit from a number?

Is there a generic way to remove the unit from a number?

Note that x / oneunit(x) sometimes doesn’t work. For instance, if you look at the Furlongs testing example defined in https://github.com/JuliaLang/julia/blob/master/test/testhelpers/Furlongs.jl, you’ll see that x / oneunit(x) gives a result of type Furlog{0} instead of a unitless number.

Maybe try Unitful.jl package, it has ustrip method for that and handles division of units well. For this particular case to unwrap you need to type x.val where x is a Furlong.

4 Likes

Generally Real(x) should work, but I don’t think it is formally part of an interface spec for unitful quantities (because there isn’t one :wink:).

A generic interface for unitful quantities that packages abide to would do some good.

I agree, but since interface expectations are not written up for Number in general this may not be something that can be fixed quickly.

I kind of expected (one(x) - zero(x)) / oneunit(x) to work for Furlong, but apparently it doesn’t, not sure if that should be reported as an issue.

In general I am not even sure that “removing unit from a number” makes sense for all types which define oneunit but not zero. I am thinking about dates of course, which count from an epoch which should be considered an implementation detail,

I think Real(x / oneunit(x)) seems like the right generic approach. You could submit a PR to change it if that doesn’t work.

If x has units that are not equivalent to “unitless” (e.g., Furlong{n} for n != 0), IMO Real(x) should throw an error. (convert(Real, x) should definitely throw an error, Real(x) is a bit less clear.) Are there packages where this (incorrectly) works? If so let’s fix it :smiling_imp:.

4 Likes

In the Furlong example, x / oneunit(x) returns a Furlong{0}. So in your opinion we should have a Real(::Furlong{0}) method?

Exactly. Or more comprehensively,

(::Type{R})(x::Furlong{0}) where R<:Real = R(x.val)

(untested)

1 Like

if rho/ρ is a vector with a unit, the following works for me as well:

convert.(Float64,  ρ ./ oneunit(ρ[1]))