Skip to content

Commit 6abef74

Browse files
committed
Add simple arithmetic (non-compound units)
1 parent e94d6ef commit 6abef74

File tree

2 files changed

+67
-25
lines changed

2 files changed

+67
-25
lines changed

src/Units.jl

+44-21
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
module Units
44

5-
import Base.show, Base.convert
5+
import Base: *, /, convert, show
66

77
export SIPrefix,
88
Quantity,
@@ -289,15 +289,16 @@ end
289289
immutable Unknown <: UnitBase end
290290

291291
# Length units
292-
immutable Meter <: UnitBase end
293-
immutable Angstrom <: UnitBase end
294-
immutable Inch <: UnitBase end
295-
immutable Foot <: UnitBase end
296-
immutable Yard <: UnitBase end
297-
immutable Mile <: UnitBase end
298-
immutable LightYear <: UnitBase end
299-
immutable Parsec <: UnitBase end
300-
immutable AstronomicalUnit <: UnitBase end
292+
abstract UnitLength <: UnitBase
293+
immutable Meter <: UnitLength end
294+
immutable Angstrom <: UnitLength end
295+
immutable Inch <: UnitLength end
296+
immutable Foot <: UnitLength end
297+
immutable Yard <: UnitLength end
298+
immutable Mile <: UnitLength end
299+
immutable LightYear <: UnitLength end
300+
immutable Parsec <: UnitLength end
301+
immutable AstronomicalUnit <: UnitLength end
301302
let
302303
# Unit RefUnit ToRef show pshow lshow fshow
303304
const utable = {
@@ -317,13 +318,14 @@ _unit_gen_dict(utable[2:end])
317318
end
318319

319320
# Time units
320-
immutable Second <: UnitBase end
321-
immutable Minute <: UnitBase end
322-
immutable Hour <: UnitBase end
323-
immutable Day <: UnitBase end
324-
immutable Week <: UnitBase end
325-
immutable YearJulian <: UnitBase end
326-
immutable PlanckTime <: UnitBase end
321+
abstract UnitTime <: UnitBase
322+
immutable Second <: UnitTime end
323+
immutable Minute <: UnitTime end
324+
immutable Hour <: UnitTime end
325+
immutable Day <: UnitTime end
326+
immutable Week <: UnitTime end
327+
immutable YearJulian <: UnitTime end
328+
immutable PlanckTime <: UnitTime end
327329
let
328330
# Unit RefUnit ToRef show pshow lshow fshow
329331
const utable = {
@@ -352,10 +354,11 @@ end
352354

353355
# Mass units
354356
# (note English units like pounds are technically weight, not mass)
355-
immutable Gram <: UnitBase end
356-
immutable AtomicMassUnit <: UnitBase end
357-
immutable Dalton <: UnitBase end
358-
immutable PlanckMass <: UnitBase end
357+
abstract UnitMass <: UnitBase
358+
immutable Gram <: UnitMass end
359+
immutable AtomicMassUnit <: UnitMass end
360+
immutable Dalton <: UnitMass end
361+
immutable PlanckMass <: UnitMass end
359362
let
360363
# Unit RefUnit ToRef show pshow lshow fshow
361364
const utable = {
@@ -454,4 +457,24 @@ function convert{Uin<:UnitBase, Uout<:UnitBase, Pin<:SIPrefix, Pout<:SIPrefix, T
454457
return Quantity(Pout, Uout, from_reference(Uout)(to_reference(Uin)(q.value*to_reference(Pin))) / to_reference(Pout))
455458
end
456459

460+
461+
# Arithmetic with Quantities
462+
(*){TP,TU}(n::Number, q::Quantity{TP,TU}) = Quantity(TP, TU, n*q.value)
463+
(*){TP,TU}(q::Quantity{TP,TU}, n::Number) = Quantity(TP, TU, n*q.value)
464+
(/){TP,TU}(q::Quantity{TP,TU}, n::Number) = Quantity(TP, TU, q.value/n)
465+
466+
(/){TP,TU<:UnitLength}(q1::Quantity{TP,TU}, q2::Quantity{TP,TU}) = q1.value/q2.value
467+
(/){TP1,TP2,TU<:UnitLength}(q1::Quantity{TP1,TU}, q2::Quantity{TP2,TU}) = q1.value/q2.value*to_reference(TP1)/to_reference(TP2)
468+
(/){TP1,TP2,TU1<:UnitLength,TU2<:UnitLength}(q1::Quantity{TP1,TU1}, q2::Quantity{TP2,TU2}) = from_reference(TU2)(to_reference(TU1)(q1.value/q2.value*to_reference(TP1)/to_reference(TP2)))
469+
(/){TP,TU<:UnitTime}(q1::Quantity{TP,TU}, q2::Quantity{TP,TU}) = q1.value/q2.value
470+
(/){TP1,TP2,TU<:UnitTime}(q1::Quantity{TP1,TU}, q2::Quantity{TP2,TU}) = q1.value/q2.value*to_reference(TP1)/to_reference(TP2)
471+
(/){TP1,TP2,TU1<:UnitTime,TU2<:UnitTime}(q1::Quantity{TP1,TU1}, q2::Quantity{TP2,TU2}) = from_reference(TU2)(to_reference(TU1)(q1.value/q2.value*to_reference(TP1)/to_reference(TP2)))
472+
(/){TP,TU<:UnitMass}(q1::Quantity{TP,TU}, q2::Quantity{TP,TU}) = q1.value/q2.value
473+
(/){TP1,TP2,TU<:UnitMass}(q1::Quantity{TP1,TU}, q2::Quantity{TP2,TU}) = q1.value/q2.value*to_reference(TP1)/to_reference(TP2)
474+
(/){TP1,TP2,TU1<:UnitMass,TU2<:UnitMass}(q1::Quantity{TP1,TU1}, q2::Quantity{TP2,TU2}) = from_reference(TU2)(to_reference(TU1)(q1.value/q2.value*to_reference(TP1)/to_reference(TP2)))
475+
476+
(/){TP,TU}(q1::Quantity{TP,TU}, q2::Quantity{TP,TU}) = q1.value/q2.value
477+
(/){TP1,TP2,TU}(q1::Quantity{TP1,TU}, q2::Quantity{TP2,TU}) = q1.value/q2.value*to_reference(TP1)/to_reference(TP2)
478+
479+
457480
end

test/units.jl

+23-4
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,36 @@
11
using Units
2+
using Base.Test
23

34
l = Quantity(Micro, Meter, 380)
4-
@assert prefix(l) == Micro
5-
@assert base(l) == Meter
5+
@test prefix(l) == Micro
6+
@test base(l) == Meter
67
pshow(l)
78
println()
89
lshow(l)
910
println()
1011
fshow(l)
1112
println()
1213
lcm = convert(Unit(Centi,Meter), l)
13-
@assert lcm.value == l.value/10^4
14+
@test lcm.value == l.value/10^4
1415

1516
temp = parse_quantity("32F")
1617
tempC = convert(Unit(SINone,Celsius), temp)
17-
println(tempC)
18+
println(temp, " = ", tempC)
19+
20+
q1 = parse_quantity("3.2 μm")
21+
q2 = parse_quantity("5.7 m")
22+
@test q2/q1 == (5.7/3.2)*1e6
23+
@test 5*q1 == Quantity(Micro, Meter, 5*3.2)
24+
@test q2/7 == Quantity(SINone, Meter, 5.7/7)
25+
26+
q1 = parse_quantity("7 s")
27+
q2 = parse_quantity("4 d")
28+
@test q1/q2 == 7/4/86400
29+
30+
q1 = parse_quantity("1 g")
31+
q2 = parse_quantity("1 Da")
32+
@test q2/q1 == 1.66053892173e-24
33+
34+
q1 = parse_quantity("3.2 μm")
35+
q2 = parse_quantity("4 d")
36+
@test_throws q1/q2

0 commit comments

Comments
 (0)