Class: Monotonic::Measurement
- Inherits:
-
Object
- Object
- Monotonic::Measurement
- Includes:
- Comparable
- Defined in:
- lib/Monotonic/Measurement.rb
Overview
An elapsed interval together with what it is worth. The count alone says nothing of how much of itself is real, so #to_s shows only as many digits as the uncertainty supports. Nothing is capped: a day resolved to a hundred nanoseconds prints every figure it has, which looks absurd and is — the absurdity being the mismatch between what the instrument resolves and what was asked of it, and better seen than rounded away.
The doubt is a Measurand's business and the unit is a Duration's; what is left here is the ladder between them and the string at the end of it.
Constant Summary collapse
- UNITS =
Powers of a thousand, and no further. The scheme is a decimal-places one, so minutes and hours have no place in it: 90s is plainer than 1.5min, and a run of a day reads as 86400s rather than reaching for a unit which does not divide by ten.
[[1, 'ns'], [1_000, 'us'], [1_000_000, 'ms'], [1_000_000_000, 's']]
Instance Attribute Summary collapse
-
#drift ⇒ Object
readonly
Returns the value of attribute drift.
-
#nanoseconds ⇒ Object
readonly
Returns the value of attribute nanoseconds.
Instance Method Summary collapse
-
#<=>(other) ⇒ Object
Against another measurement only.
-
#decimals ⇒ Object
The least significant digit worth showing is the one the uncertainty reaches, which Measurand settles by the Particle Data Group convention and reports as #place, a power of ten.
-
#floor ⇒ Object
The floor may be given as a number or as anything which answers to #call, so that measuring it can wait until somebody asks about doubt.
- #inspect ⇒ Object
-
#measurand ⇒ Object
The floor is absolute and tells upon short intervals; drift is relative and tells upon long ones, being the rate at which the clock's own oscillator wanders.
- #scale ⇒ Object
- #to_duration ⇒ Object
- #to_f ⇒ Object
-
#to_i ⇒ Object
Both answer in nanoseconds, this measurement's own unit, as Duration::Minutes answers 5 rather than 300.
- #to_s ⇒ Object
- #uncertainty ⇒ Object
- #unit ⇒ Object
- #unit_name ⇒ Object
Instance Attribute Details
#drift ⇒ Object (readonly)
Returns the value of attribute drift.
27 28 29 |
# File 'lib/Monotonic/Measurement.rb', line 27 def drift @drift end |
#nanoseconds ⇒ Object (readonly)
Returns the value of attribute nanoseconds.
26 27 28 |
# File 'lib/Monotonic/Measurement.rb', line 26 def nanoseconds @nanoseconds end |
Instance Method Details
#<=>(other) ⇒ Object
Against another measurement only. A bare number has no unit, and comparing against one would have to assume which was meant, so nil is returned and == is false, as Duration::Common does.
101 102 103 104 |
# File 'lib/Monotonic/Measurement.rb', line 101 def <=>(other) return nil unless other.is_a?(Monotonic::Measurement) @nanoseconds <=> other.nanoseconds end |
#decimals ⇒ Object
The least significant digit worth showing is the one the uncertainty reaches, which Measurand settles by the Particle Data Group convention and reports as #place, a power of ten. Rendering in a coarser unit moves it along by however many tens that unit is worth. A measurand with no uncertainty has no last real digit, and answers nil.
71 72 73 74 75 76 |
# File 'lib/Monotonic/Measurement.rb', line 71 def decimals @decimals ||= ( place = measurand.place place ? [Math.log10(scale) - place, 0].max.to_i : Math.log10(scale).to_i ) end |
#floor ⇒ Object
The floor may be given as a number or as anything which answers to #call, so that measuring it can wait until somebody asks about doubt. Monotonic::Timer hands over its .floor method rather than its value, and a caller which only wants a number never sets the thousand null measurements going.
34 35 36 |
# File 'lib/Monotonic/Measurement.rb', line 34 def floor @floor = @floor.respond_to?(:call) ? @floor.call : @floor end |
#inspect ⇒ Object
106 107 108 |
# File 'lib/Monotonic/Measurement.rb', line 106 def inspect "#<#{self.class} #{self} (#{measurand} ns)>" end |
#measurand ⇒ Object
The floor is absolute and tells upon short intervals; drift is relative and tells upon long ones, being the rate at which the clock's own oscillator wanders. Combining them is not addition — they are independent, so they go in quadrature — which is why the arithmetic is Measurand's and not done here.
43 44 45 46 47 48 |
# File 'lib/Monotonic/Measurement.rb', line 43 def measurand @measurand ||= ( absolute = Measurand.new(@nanoseconds, floor) @drift ? absolute * Measurand.relative(1, @drift) : absolute ) end |
#scale ⇒ Object
58 59 60 |
# File 'lib/Monotonic/Measurement.rb', line 58 def scale unit.first end |
#to_duration ⇒ Object
78 79 80 |
# File 'lib/Monotonic/Measurement.rb', line 78 def to_duration Duration::Nanoseconds.new(@nanoseconds) end |
#to_f ⇒ Object
90 91 92 |
# File 'lib/Monotonic/Measurement.rb', line 90 def to_f @nanoseconds.to_f end |
#to_i ⇒ Object
Both answer in nanoseconds, this measurement's own unit, as Duration::Minutes answers 5 rather than 300. Every other unit comes from #to_duration, which names the one it is asked for. A number handed out without its unit stated must at least always mean the same thing.
86 87 88 |
# File 'lib/Monotonic/Measurement.rb', line 86 def to_i @nanoseconds end |
#to_s ⇒ Object
94 95 96 |
# File 'lib/Monotonic/Measurement.rb', line 94 def to_s format("%.#{decimals}f #{unit_name}", @nanoseconds.to_f / scale) end |
#uncertainty ⇒ Object
50 51 52 |
# File 'lib/Monotonic/Measurement.rb', line 50 def uncertainty measurand.uncertainty end |
#unit ⇒ Object
54 55 56 |
# File 'lib/Monotonic/Measurement.rb', line 54 def unit @unit ||= UNITS.reverse.find{|scale, _| @nanoseconds.abs >= scale} || UNITS.first end |
#unit_name ⇒ Object
62 63 64 |
# File 'lib/Monotonic/Measurement.rb', line 62 def unit_name unit.last end |