Repository: open-telemetry/opentelemetry-go
Pull request #1316 (2020-11-09 14:44:07)

Prepare to move metrics code to separate subpackage
Metric is quite a hefty amount of code to be moved around, so split the move by moving the registry and number code into the metric subpackage. This PR comes as a part of solving #1303.

Resolves https://github.com/open-telemetry/opentelemetry-go/issues/1287

krnowak: Updated and rebased. The CI failure seems to be a flake, not related to my changes.

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 20a50302..842b2c49 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -31,7 +31,9 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
    This matches the returned type and fixes misuse of the term metric. (#1240)
 - Move test harness from the `go.opentelemetry.io/otel/api/apitest` package into `go.opentelemetry.io/otel/oteltest`. (#1241)
 - Rename `MergeItererator` to `MergeIterator` in the `go.opentelemetry.io/otel/label` package. (#1244)
-- Move the `go.opentelemetry.io/otel/api/metric`, `go.opentelemetry.io/otel/api/metric/metrictest`, and `go.opentelemetry.io/otel/api/metric/registry` packages into `go.opentelemetry.io/otel` as part of #964. (#1252)
+- Move the `go.opentelemetry.io/otel/api/metric` and `go.opentelemetry.io/otel/api/metric/metrictest` packages into `go.opentelemetry.io/otel` as part of #964. (#1252)
+- Move the `go.opentelemetry.io/otel/api/metric/registry` package into `go.opentelemetry.io/otel/metric/registry as a part of #1303. (#1316)
+- Move the `Number` type (together with related functions) from `go.opentelemetry.io/otel/api/metric` package into `go.opentelemetry.io/otel/metric/number` as a part of #1303. (#1316)
 - The function signature of the Span `AddEvent` method in `go.opentelemetry.io/otel` is updated to no longer take an unused context and instead take a required name and a variable number of `EventOption`s. (#1254)
 - The function signature of the Span `RecordError` method in `go.opentelemetry.io/otel` is updated to no longer take an unused context and instead take a required error value and a variable number of `EventOption`s. (#1254)
 - Move the `go.opentelemetry.io/otel/api/global` package to `go.opentelemetry.io/otel/global`. (#1262)
diff --git a/exporters/metric/prometheus/prometheus.go b/exporters/metric/prometheus/prometheus.go
index 6d047954..389f7e49 100644
--- a/exporters/metric/prometheus/prometheus.go
+++ b/exporters/metric/prometheus/prometheus.go
@@ -26,6 +26,7 @@ import (
 	"go.opentelemetry.io/otel"
 	"go.opentelemetry.io/otel/global"
 	"go.opentelemetry.io/otel/label"
+	"go.opentelemetry.io/otel/metric/number"
 	export "go.opentelemetry.io/otel/sdk/export/metric"
 	"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
 	"go.opentelemetry.io/otel/sdk/metric/controller/pull"
@@ -257,7 +258,7 @@ func (c *collector) Collect(ch chan<- prometheus.Metric) {
 	}
 }
 
-func (c *collector) exportLastValue(ch chan<- prometheus.Metric, lvagg aggregation.LastValue, kind otel.NumberKind, desc *prometheus.Desc, labels []string) error {
+func (c *collector) exportLastValue(ch chan<- prometheus.Metric, lvagg aggregation.LastValue, kind number.Kind, desc *prometheus.Desc, labels []string) error {
 	lv, _, err := lvagg.LastValue()
 	if err != nil {
 		return fmt.Errorf("error retrieving last value: %w", err)
@@ -272,7 +273,7 @@ func (c *collector) exportLastValue(ch chan<- prometheus.Metric, lvagg aggregati
 	return nil
 }
 
-func (c *collector) exportNonMonotonicCounter(ch chan<- prometheus.Metric, sum aggregation.Sum, kind otel.NumberKind, desc *prometheus.Desc, labels []string) error {
+func (c *collector) exportNonMonotonicCounter(ch chan<- prometheus.Metric, sum aggregation.Sum, kind number.Kind, desc *prometheus.Desc, labels []string) error {
 	v, err := sum.Sum()
 	if err != nil {
 		return fmt.Errorf("error retrieving counter: %w", err)
@@ -287,7 +288,7 @@ func (c *collector) exportNonMonotonicCounter(ch chan<- prometheus.Metric, sum a
 	return nil
 }
 
-func (c *collector) exportMonotonicCounter(ch chan<- prometheus.Metric, sum aggregation.Sum, kind otel.NumberKind, desc *prometheus.Desc, labels []string) error {
+func (c *collector) exportMonotonicCounter(ch chan<- prometheus.Metric, sum aggregation.Sum, kind number.Kind, desc *prometheus.Desc, labels []string) error {
 	v, err := sum.Sum()
 	if err != nil {
 		return fmt.Errorf("error retrieving counter: %w", err)
@@ -302,13 +303,13 @@ func (c *collector) exportMonotonicCounter(ch chan<- prometheus.Metric, sum aggr
 	return nil
 }
 
-func (c *collector) exportSummary(ch chan<- prometheus.Metric, dist aggregation.Distribution, kind otel.NumberKind, desc *prometheus.Desc, labels []string) error {
+func (c *collector) exportSummary(ch chan<- prometheus.Metric, dist aggregation.Distribution, kind number.Kind, desc *prometheus.Desc, labels []string) error {
 	count, err := dist.Count()
 	if err != nil {
 		return fmt.Errorf("error retrieving count: %w", err)
 	}
 
-	var sum otel.Number
+	var sum number.Number
 	sum, err = dist.Sum()
 	if err != nil {
 		return fmt.Errorf("error retrieving distribution sum: %w", err)
@@ -329,7 +330,7 @@ func (c *collector) exportSummary(ch chan<- prometheus.Metric, dist aggregation.
 	return nil
 }
 
-func (c *collector) exportHistogram(ch chan<- prometheus.Metric, hist aggregation.Histogram, kind otel.NumberKind, desc *prometheus.Desc, labels []string) error {
+func (c *collector) exportHistogram(ch chan<- prometheus.Metric, hist aggregation.Histogram, kind number.Kind, desc *prometheus.Desc, labels []string) error {
 	buckets, err := hist.Histogram()
 	if err != nil {
 		return fmt.Errorf("error retrieving histogram: %w", err)
diff --git a/exporters/otlp/internal/transform/metric.go b/exporters/otlp/internal/transform/metric.go
index 04bd3fcc..20b063c3 100644
--- a/exporters/otlp/internal/transform/metric.go
+++ b/exporters/otlp/internal/transform/metric.go
@@ -24,12 +24,12 @@ import (
 	"sync"
 	"time"
 
-	"go.opentelemetry.io/otel"
 	commonpb "go.opentelemetry.io/otel/exporters/otlp/internal/opentelemetry-proto-gen/common/v1"
 	metricpb "go.opentelemetry.io/otel/exporters/otlp/internal/opentelemetry-proto-gen/metrics/v1"
 	resourcepb "go.opentelemetry.io/otel/exporters/otlp/internal/opentelemetry-proto-gen/resource/v1"
 
 	"go.opentelemetry.io/otel/label"
+	"go.opentelemetry.io/otel/metric/number"
 	export "go.opentelemetry.io/otel/sdk/export/metric"
 	"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
 	"go.opentelemetry.io/otel/sdk/instrumentation"
@@ -294,7 +294,7 @@ func Record(exportSelector export.ExportKindSelector, r export.Record) (*metricp
 	}
 }
 
-func gaugePoint(record export.Record, num otel.Number, start, end time.Time) (*metricpb.Metric, error) {
+func gaugePoint(record export.Record, num number.Number, start, end time.Time) (*metricpb.Metric, error) {
 	desc := record.Descriptor()
 	labels := record.Labels()
 
@@ -305,7 +305,7 @@ func gaugePoint(record export.Record, num otel.Number, start, end time.Time) (*m
 	}
 
 	switch n := desc.NumberKind(); n {
-	case otel.Int64NumberKind:
+	case number.Int64Kind:
 		m.Data = &metricpb.Metric_IntGauge{
 			IntGauge: &metricpb.IntGauge{
 				DataPoints: []*metricpb.IntDataPoint{
@@ -318,7 +318,7 @@ func gaugePoint(record export.Record, num otel.Number, start, end time.Time) (*m
 				},
 			},
 		}
-	case otel.Float64NumberKind:
+	case number.Float64Kind:
 		m.Data = &metricpb.Metric_DoubleGauge{
 			DoubleGauge: &metricpb.DoubleGauge{
 				DataPoints: []*metricpb.DoubleDataPoint{
@@ -348,7 +348,7 @@ func exportKindToTemporality(ek export.ExportKind) metricpb.AggregationTemporali
 	return metricpb.AggregationTemporality_AGGREGATION_TEMPORALITY_UNSPECIFIED
 }
 
-func sumPoint(record export.Record, num otel.Number, start, end time.Time, ek export.ExportKind, monotonic bool) (*metricpb.Metric, error) {
+func sumPoint(record export.Record, num number.Number, start, end time.Time, ek export.ExportKind, monotonic bool) (*metricpb.Metric, error) {
 	desc := record.Descriptor()
 	labels := record.Labels()
 
@@ -359,7 +359,7 @@ func sumPoint(record export.Record, num otel.Number, start, end time.Time, ek ex
 	}
 
 	switch n := desc.NumberKind(); n {
-	case otel.Int64NumberKind:
+	case number.Int64Kind:
 		m.Data = &metricpb.Metric_IntSum{
 			IntSum: &metricpb.IntSum{
 				IsMonotonic:            monotonic,
@@ -374,7 +374,7 @@ func sumPoint(record export.Record, num otel.Number, start, end time.Time, ek ex
 				},
 			},
 		}
-	case otel.Float64NumberKind:
+	case number.Float64Kind:
 		m.Data = &metricpb.Metric_DoubleSum{
 			DoubleSum: &metricpb.DoubleSum{
 				IsMonotonic:            monotonic,
@@ -398,7 +398,7 @@ func sumPoint(record export.Record, num otel.Number, start, end time.Time, ek ex
 
 // minMaxSumCountValue returns the values of the MinMaxSumCount Aggregator
 // as discrete values.
-func minMaxSumCountValues(a aggregation.MinMaxSumCount) (min, max, sum otel.Number, count int64, err error) {
+func minMaxSumCountValues(a aggregation.MinMaxSumCount) (min, max, sum number.Number, count int64, err error) {
 	if min, err = a.Min(); err != nil {
 		return
 	}
@@ -433,7 +433,7 @@ func minMaxSumCount(record export.Record, a aggregation.MinMaxSumCount) (*metric
 	bounds := []float64{0.0, 100.0}
 
 	switch n := desc.NumberKind(); n {
-	case otel.Int64NumberKind:
+	case number.Int64Kind:
 		m.Data = &metricpb.Metric_IntHistogram{
 			IntHistogram: &metricpb.IntHistogram{
 				DataPoints: []*metricpb.IntHistogramDataPoint{
@@ -449,7 +449,7 @@ func minMaxSumCount(record export.Record, a aggregation.MinMaxSumCount) (*metric
 				},
 			},
 		}
-	case otel.Float64NumberKind:
+	case number.Float64Kind:
 		m.Data = &metricpb.Metric_DoubleHistogram{
 			DoubleHistogram: &metricpb.DoubleHistogram{
 				DataPoints: []*metricpb.DoubleHistogramDataPoint{
@@ -513,7 +513,7 @@ func histogramPoint(record export.Record, ek export.ExportKind, a aggregation.Hi
 		Unit:        string(desc.Unit()),
 	}
 	switch n := desc.NumberKind(); n {
-	case otel.Int64NumberKind:
+	case number.Int64Kind:
 		m.Data = &metricpb.Metric_IntHistogram{
 			IntHistogram: &metricpb.IntHistogram{
 				AggregationTemporality: exportKindToTemporality(ek),
@@ -530,7 +530,7 @@ func histogramPoint(record export.Record, ek export.ExportKind, a aggregation.Hi
 				},
 			},
 		}
-	case otel.Float64NumberKind:
+	case number.Float64Kind:
 		m.Data = &metricpb.Metric_DoubleHistogram{
 			DoubleHistogram: &metricpb.DoubleHistogram{
 				AggregationTemporality: exportKindToTemporality(ek),
diff --git a/global/internal/meter.go b/global/internal/meter.go
index 1549059b..254be912 100644
--- a/global/internal/meter.go
+++ b/global/internal/meter.go
@@ -22,7 +22,8 @@ import (
 
 	"go.opentelemetry.io/otel"
 	"go.opentelemetry.io/otel/label"
-	"go.opentelemetry.io/otel/registry"
+	"go.opentelemetry.io/otel/metric/number"
+	"go.opentelemetry.io/otel/metric/registry"
 )
 
 // This file contains the forwarding implementation of MeterProvider used as
@@ -305,7 +306,7 @@ func (m *meterImpl) RecordBatch(ctx context.Context, labels []label.KeyValue, me
 	}
 }
 
-func (inst *syncImpl) RecordOne(ctx context.Context, number otel.Number, labels []label.KeyValue) {
+func (inst *syncImpl) RecordOne(ctx context.Context, number number.Number, labels []label.KeyValue) {
 	if instPtr := (*otel.SyncImpl)(atomic.LoadPointer(&inst.delegate)); instPtr != nil {
 		(*instPtr).RecordOne(ctx, number, labels)
 	}
@@ -313,7 +314,7 @@ func (inst *syncImpl) RecordOne(ctx context.Context, number otel.Number, labels
 
 // Bound instrument initialization
 
-func (bound *syncHandle) RecordOne(ctx context.Context, number otel.Number) {
+func (bound *syncHandle) RecordOne(ctx context.Context, number number.Number) {
 	instPtr := (*otel.SyncImpl)(atomic.LoadPointer(&bound.inst.delegate))
 	if instPtr == nil {
 		return
diff --git a/metric.go b/metric.go
index b06ae8db..c5094e4d 100644
--- a/metric.go
+++ b/metric.go
@@ -18,6 +18,7 @@ import (
 	"context"
 
 	"go.opentelemetry.io/otel/label"
+	"go.opentelemetry.io/otel/metric/number"
 	"go.opentelemetry.io/otel/unit"
 )
 
@@ -63,7 +64,7 @@ func (m Meter) NewBatchObserver(callback BatchObserverFunc) BatchObserver {
 // duplicate registration).
 func (m Meter) NewInt64Counter(name string, options ...InstrumentOption) (Int64Counter, error) {
 	return wrapInt64CounterInstrument(
-		m.newSync(name, CounterInstrumentKind, Int64NumberKind, options))
+		m.newSync(name, CounterInstrumentKind, number.Int64Kind, options))
 }
 
 // NewFloat64Counter creates a new floating point Counter with the
@@ -72,7 +73,7 @@ func (m Meter) NewInt64Counter(name string, options ...InstrumentOption) (Int64C
 // duplicate registration).
 func (m Meter) NewFloat64Counter(name string, options ...InstrumentOption) (Float64Counter, error) {
 	return wrapFloat64CounterInstrument(
-		m.newSync(name, CounterInstrumentKind, Float64NumberKind, options))
+		m.newSync(name, CounterInstrumentKind, number.Float64Kind, options))
 }
 
 // NewInt64UpDownCounter creates a new integer UpDownCounter instrument with the
@@ -81,7 +82,7 @@ func (m Meter) NewFloat64Counter(name string, options ...InstrumentOption) (Floa
 // duplicate registration).
 func (m Meter) NewInt64UpDownCounter(name string, options ...InstrumentOption) (Int64UpDownCounter, error) {
 	return wrapInt64UpDownCounterInstrument(
-		m.newSync(name, UpDownCounterInstrumentKind, Int64NumberKind, options))
+		m.newSync(name, UpDownCounterInstrumentKind, number.Int64Kind, options))
 }
 
 // NewFloat64UpDownCounter creates a new floating point UpDownCounter with the
@@ -90,7 +91,7 @@ func (m Meter) NewInt64UpDownCounter(name string, options ...InstrumentOption) (
 // duplicate registration).
 func (m Meter) NewFloat64UpDownCounter(name string, options ...InstrumentOption) (Float64UpDownCounter, error) {
 	return wrapFloat64UpDownCounterInstrument(
-		m.newSync(name, UpDownCounterInstrumentKind, Float64NumberKind, options))
+		m.newSync(name, UpDownCounterInstrumentKind, number.Float64Kind, options))
 }
 
 // NewInt64ValueRecorder creates a new integer ValueRecorder instrument with the
@@ -99,7 +100,7 @@ func (m Meter) NewFloat64UpDownCounter(name string, options ...InstrumentOption)
 // duplicate registration).
 func (m Meter) NewInt64ValueRecorder(name string, opts ...InstrumentOption) (Int64ValueRecorder, error) {
 	return wrapInt64ValueRecorderInstrument(
-		m.newSync(name, ValueRecorderInstrumentKind, Int64NumberKind, opts))
+		m.newSync(name, ValueRecorderInstrumentKind, number.Int64Kind, opts))
 }
 
 // NewFloat64ValueRecorder creates a new floating point ValueRecorder with the
@@ -108,7 +109,7 @@ func (m Meter) NewInt64ValueRecorder(name string, opts ...InstrumentOption) (Int
 // duplicate registration).
 func (m Meter) NewFloat64ValueRecorder(name string, opts ...InstrumentOption) (Float64ValueRecorder, error) {
 	return wrapFloat64ValueRecorderInstrument(
-		m.newSync(name, ValueRecorderInstrumentKind, Float64NumberKind, opts))
+		m.newSync(name, ValueRecorderInstrumentKind, number.Float64Kind, opts))
 }
 
 // NewInt64ValueObserver creates a new integer ValueObserver instrument
@@ -120,7 +121,7 @@ func (m Meter) NewInt64ValueObserver(name string, callback Int64ObserverFunc, op
 		return wrapInt64ValueObserverInstrument(NoopAsync{}, nil)
 	}
 	return wrapInt64ValueObserverInstrument(
-		m.newAsync(name, ValueObserverInstrumentKind, Int64NumberKind, opts,
+		m.newAsync(name, ValueObserverInstrumentKind, number.Int64Kind, opts,
 			newInt64AsyncRunner(callback)))
 }
 
@@ -133,7 +134,7 @@ func (m Meter) NewFloat64ValueObserver(name string, callback Float64ObserverFunc
 		return wrapFloat64ValueObserverInstrument(NoopAsync{}, nil)
 	}
 	return wrapFloat64ValueObserverInstrument(
-		m.newAsync(name, ValueObserverInstrumentKind, Float64NumberKind, opts,
+		m.newAsync(name, ValueObserverInstrumentKind, number.Float64Kind, opts,
 			newFloat64AsyncRunner(callback)))
 }
 
@@ -146,7 +147,7 @@ func (m Meter) NewInt64SumObserver(name string, callback Int64ObserverFunc, opts
 		return wrapInt64SumObserverInstrument(NoopAsync{}, nil)
 	}
 	return wrapInt64SumObserverInstrument(
-		m.newAsync(name, SumObserverInstrumentKind, Int64NumberKind, opts,
+		m.newAsync(name, SumObserverInstrumentKind, number.Int64Kind, opts,
 			newInt64AsyncRunner(callback)))
 }
 
@@ -159,7 +160,7 @@ func (m Meter) NewFloat64SumObserver(name string, callback Float64ObserverFunc,
 		return wrapFloat64SumObserverInstrument(NoopAsync{}, nil)
 	}
 	return wrapFloat64SumObserverInstrument(
-		m.newAsync(name, SumObserverInstrumentKind, Float64NumberKind, opts,
+		m.newAsync(name, SumObserverInstrumentKind, number.Float64Kind, opts,
 			newFloat64AsyncRunner(callback)))
 }
 
@@ -172,7 +173,7 @@ func (m Meter) NewInt64UpDownSumObserver(name string, callback Int64ObserverFunc
 		return wrapInt64UpDownSumObserverInstrument(NoopAsync{}, nil)
 	}
 	return wrapInt64UpDownSumObserverInstrument(
-		m.newAsync(name, UpDownSumObserverInstrumentKind, Int64NumberKind, opts,
+		m.newAsync(name, UpDownSumObserverInstrumentKind, number.Int64Kind, opts,
 			newInt64AsyncRunner(callback)))
 }
 
@@ -185,7 +186,7 @@ func (m Meter) NewFloat64UpDownSumObserver(name string, callback Float64Observer
 		return wrapFloat64UpDownSumObserverInstrument(NoopAsync{}, nil)
 	}
 	return wrapFloat64UpDownSumObserverInstrument(
-		m.newAsync(name, UpDownSumObserverInstrumentKind, Float64NumberKind, opts,
+		m.newAsync(name, UpDownSumObserverInstrumentKind, number.Float64Kind, opts,
 			newFloat64AsyncRunner(callback)))
 }
 
@@ -198,7 +199,7 @@ func (b BatchObserver) NewInt64ValueObserver(name string, opts ...InstrumentOpti
 		return wrapInt64ValueObserverInstrument(NoopAsync{}, nil)
 	}
 	return wrapInt64ValueObserverInstrument(
-		b.meter.newAsync(name, ValueObserverInstrumentKind, Int64NumberKind, opts, b.runner))
+		b.meter.newAsync(name, ValueObserverInstrumentKind, number.Int64Kind, opts, b.runner))
 }
 
 // NewFloat64ValueObserver creates a new floating point ValueObserver with
@@ -210,7 +211,7 @@ func (b BatchObserver) NewFloat64ValueObserver(name string, opts ...InstrumentOp
 		return wrapFloat64ValueObserverInstrument(NoopAsync{}, nil)
 	}
 	return wrapFloat64ValueObserverInstrument(
-		b.meter.newAsync(name, ValueObserverInstrumentKind, Float64NumberKind, opts,
+		b.meter.newAsync(name, ValueObserverInstrumentKind, number.Float64Kind, opts,
 			b.runner))
 }
 
@@ -223,7 +224,7 @@ func (b BatchObserver) NewInt64SumObserver(name string, opts ...InstrumentOption
 		return wrapInt64SumObserverInstrument(NoopAsync{}, nil)
 	}
 	return wrapInt64SumObserverInstrument(
-		b.meter.newAsync(name, SumObserverInstrumentKind, Int64NumberKind, opts, b.runner))
+		b.meter.newAsync(name, SumObserverInstrumentKind, number.Int64Kind, opts, b.runner))
 }
 
 // NewFloat64SumObserver creates a new floating point SumObserver with
@@ -235,7 +236,7 @@ func (b BatchObserver) NewFloat64SumObserver(name string, opts ...InstrumentOpti
 		return wrapFloat64SumObserverInstrument(NoopAsync{}, nil)
 	}
 	return wrapFloat64SumObserverInstrument(
-		b.meter.newAsync(name, SumObserverInstrumentKind, Float64NumberKind, opts,
+		b.meter.newAsync(name, SumObserverInstrumentKind, number.Float64Kind, opts,
 			b.runner))
 }
 
@@ -248,7 +249,7 @@ func (b BatchObserver) NewInt64UpDownSumObserver(name string, opts ...Instrument
 		return wrapInt64UpDownSumObserverInstrument(NoopAsync{}, nil)
 	}
 	return wrapInt64UpDownSumObserverInstrument(
-		b.meter.newAsync(name, UpDownSumObserverInstrumentKind, Int64NumberKind, opts, b.runner))
+		b.meter.newAsync(name, UpDownSumObserverInstrumentKind, number.Int64Kind, opts, b.runner))
 }
 
 // NewFloat64UpDownSumObserver creates a new floating point UpDownSumObserver with
@@ -260,7 +261,7 @@ func (b BatchObserver) NewFloat64UpDownSumObserver(name string, opts ...Instrume
 		return wrapFloat64UpDownSumObserverInstrument(NoopAsync{}, nil)
 	}
 	return wrapFloat64UpDownSumObserverInstrument(
-		b.meter.newAsync(name, UpDownSumObserverInstrumentKind, Float64NumberKind, opts,
+		b.meter.newAsync(name, UpDownSumObserverInstrumentKind, number.Float64Kind, opts,
 			b.runner))
 }
 
@@ -273,7 +274,7 @@ func (m Meter) MeterImpl() MeterImpl {
 func (m Meter) newAsync(
 	name string,
 	mkind InstrumentKind,
-	nkind NumberKind,
+	nkind number.Kind,
 	opts []InstrumentOption,
 	runner AsyncRunner,
 ) (
@@ -293,7 +294,7 @@ func (m Meter) newAsync(
 func (m Meter) newSync(
 	name string,
 	metricKind InstrumentKind,
-	numberKind NumberKind,
+	numberKind number.Kind,
 	opts []InstrumentOption,
 ) (
 	SyncImpl,
@@ -521,12 +522,12 @@ func (bm BatchObserverMust) NewFloat64UpDownSumObserver(name string, oos ...Inst
 type Descriptor struct {
 	name           string
 	instrumentKind InstrumentKind
-	numberKind     NumberKind
+	numberKind     number.Kind
 	config         InstrumentConfig
 }
 
 // NewDescriptor returns a Descriptor with the given contents.
-func NewDescriptor(name string, ikind InstrumentKind, nkind NumberKind, opts ...InstrumentOption) Descriptor {
+func NewDescriptor(name string, ikind InstrumentKind, nkind number.Kind, opts ...InstrumentOption) Descriptor {
 	return Descriptor{
 		name:           name,
 		instrumentKind: ikind,
@@ -559,7 +560,7 @@ func (d Descriptor) Unit() unit.Unit {
 
 // NumberKind returns whether this instrument is declared over int64,
 // float64, or uint64 values.
-func (d Descriptor) NumberKind() NumberKind {
+func (d Descriptor) NumberKind() number.Kind {
 	return d.numberKind
 }
 
diff --git a/metric/number/kind_string.go b/metric/number/kind_string.go
new file mode 100644
index 00000000..6288c7ea
--- /dev/null
+++ b/metric/number/kind_string.go
@@ -0,0 +1,24 @@
+// Code generated by "stringer -type=Kind"; DO NOT EDIT.
+
+package number
+
+import "strconv"
+
+func _() {
+	// An "invalid array index" compiler error signifies that the constant values have changed.
+	// Re-run the stringer command to generate them again.
+	var x [1]struct{}
+	_ = x[Int64Kind-0]
+	_ = x[Float64Kind-1]
+}
+
+const _Kind_name = "Int64KindFloat64Kind"
+
+var _Kind_index = [...]uint8{0, 9, 20}
+
+func (i Kind) String() string {
+	if i < 0 || i >= Kind(len(_Kind_index)-1) {
+		return "Kind(" + strconv.FormatInt(int64(i), 10) + ")"
+	}
+	return _Kind_name[_Kind_index[i]:_Kind_index[i+1]]
+}
diff --git a/number.go b/metric/number/number.go
similarity index 85%
rename from number.go
rename to metric/number/number.go
index 411bfcf7..3ec95e20 100644
--- a/number.go
+++ b/metric/number/number.go
@@ -12,9 +12,9 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package otel // import "go.opentelemetry.io/otel"
+package number // import "go.opentelemetry.io/otel/metric/number"
 
-//go:generate stringer -type=NumberKind
+//go:generate stringer -type=Kind
 
 import (
 	"fmt"
@@ -24,22 +24,22 @@ import (
 	"go.opentelemetry.io/otel/internal"
 )
 
-// NumberKind describes the data type of the Number.
-type NumberKind int8
+// Kind describes the data type of the Number.
+type Kind int8
 
 const (
-	// Int64NumberKind means that the Number stores int64.
-	Int64NumberKind NumberKind = iota
-	// Float64NumberKind means that the Number stores float64.
-	Float64NumberKind
+	// Int64Kind means that the Number stores int64.
+	Int64Kind Kind = iota
+	// Float64Kind means that the Number stores float64.
+	Float64Kind
 )
 
-// Zero returns a zero value for a given NumberKind
-func (k NumberKind) Zero() Number {
+// Zero returns a zero value for a given Kind
+func (k Kind) Zero() Number {
 	switch k {
-	case Int64NumberKind:
+	case Int64Kind:
 		return NewInt64Number(0)
-	case Float64NumberKind:
+	case Float64Kind:
 		return NewFloat64Number(0.)
 	default:
 		return Number(0)
@@ -47,12 +47,12 @@ func (k NumberKind) Zero() Number {
 }
 
 // Minimum returns the minimum representable value
-// for a given NumberKind
-func (k NumberKind) Minimum() Number {
+// for a given Kind
+func (k Kind) Minimum() Number {
 	switch k {
-	case Int64NumberKind:
+	case Int64Kind:
 		return NewInt64Number(math.MinInt64)
-	case Float64NumberKind:
+	case Float64Kind:
 		return NewFloat64Number(-1. * math.MaxFloat64)
 	default:
 		return Number(0)
@@ -60,12 +60,12 @@ func (k NumberKind) Minimum() Number {
 }
 
 // Maximum returns the maximum representable value
-// for a given NumberKind
-func (k NumberKind) Maximum() Number {
+// for a given Kind
+func (k Kind) Maximum() Number {
 	switch k {
-	case Int64NumberKind:
+	case Int64Kind:
 		return NewInt64Number(math.MaxInt64)
-	case Float64NumberKind:
+	case Float64Kind:
 		return NewFloat64Number(math.MaxFloat64)
 	default:
 		return Number(0)
@@ -73,7 +73,7 @@ func (k NumberKind) Maximum() Number {
 }
 
 // Number represents either an integral or a floating point value. It
-// needs to be accompanied with a source of NumberKind that describes
+// needs to be accompanied with a source of Kind that describes
 // the actual type of the value stored within Number.
 type Number uint64
 
@@ -96,13 +96,11 @@ func NewFloat64Number(f float64) Number {
 
 // NewNumberSignChange returns a number with the same magnitude and
 // the opposite sign.  `kind` must describe the kind of number in `nn`.
-//
-// Does not change Uint64NumberKind values.
-func NewNumberSignChange(kind NumberKind, nn Number) Number {
+func NewNumberSignChange(kind Kind, nn Number) Number {
 	switch kind {
-	case Int64NumberKind:
+	case Int64Kind:
 		return NewInt64Number(-nn.AsInt64())
-	case Float64NumberKind:
+	case Float64Kind:
 		return NewFloat64Number(-nn.AsFloat64())
 	}
 	return nn
@@ -182,11 +180,11 @@ func (n *Number) AsFloat64Ptr() *float64 {
 
 // CoerceToInt64 casts the number to int64. May result in
 // data/precision loss.
-func (n *Number) CoerceToInt64(kind NumberKind) int64 {
+func (n *Number) CoerceToInt64(kind Kind) int64 {
 	switch kind {
-	case Int64NumberKind:
+	case Int64Kind:
 		return n.AsInt64()
-	case Float64NumberKind:
+	case Float64Kind:
 		return int64(n.AsFloat64())
 	default:
 		// you get what you deserve
@@ -196,11 +194,11 @@ func (n *Number) CoerceToInt64(kind NumberKind) int64 {
 
 // CoerceToFloat64 casts the number to float64. May result in
 // data/precision loss.
-func (n *Number) CoerceToFloat64(kind NumberKind) float64 {
+func (n *Number) CoerceToFloat64(kind Kind) float64 {
 	switch kind {
-	case Int64NumberKind:
+	case Int64Kind:
 		return float64(n.AsInt64())
-	case Float64NumberKind:
+	case Float64Kind:
 		return n.AsFloat64()
 	default:
 		// you get what you deserve
@@ -330,18 +328,18 @@ func (n *Number) SwapFloat64Atomic(f float64) float64 {
 
 // AddNumber assumes that this and the passed number are of the passed
 // kind and adds the passed number to this number.
-func (n *Number) AddNumber(kind NumberKind, nn Number) {
+func (n *Number) AddNumber(kind Kind, nn Number) {
 	switch kind {
-	case Int64NumberKind:
+	case Int64Kind:
 		n.AddInt64(nn.AsInt64())
-	case Float64NumberKind:
+	case Float64Kind:
 		n.AddFloat64(nn.AsFloat64())
 	}
 }
 
 // AddRaw assumes that this number and the passed raw value are of the
 // passed kind and adds the passed raw value to this number.
-func (n *Number) AddRaw(kind NumberKind, r uint64) {
+func (n *Number) AddRaw(kind Kind, r uint64) {
 	n.AddNumber(kind, NewNumberFromRaw(r))
 }
 
@@ -361,11 +359,11 @@ func (n *Number) AddFloat64(f float64) {
 
 // AddNumberAtomic assumes that this and the passed number are of the
 // passed kind and adds the passed number to this number atomically.
-func (n *Number) AddNumberAtomic(kind NumberKind, nn Number) {
+func (n *Number) AddNumberAtomic(kind Kind, nn Number) {
 	switch kind {
-	case Int64NumberKind:
+	case Int64Kind:
 		n.AddInt64Atomic(nn.AsInt64())
-	case Float64NumberKind:
+	case Float64Kind:
 		n.AddFloat64Atomic(nn.AsFloat64())
 	}
 }
@@ -373,7 +371,7 @@ func (n *Number) AddNumberAtomic(kind NumberKind, nn Number) {
 // AddRawAtomic assumes that this number and the passed raw value are
 // of the passed kind and adds the passed raw value to this number
 // atomically.
-func (n *Number) AddRawAtomic(kind NumberKind, r uint64) {
+func (n *Number) AddRawAtomic(kind Kind, r uint64) {
 	n.AddNumberAtomic(kind, NewNumberFromRaw(r))
 }
 
@@ -429,11 +427,11 @@ func (n *Number) CompareAndSwapFloat64(of, nf float64) bool {
 //    0 if the numbers are equal
 //    -1 if the subject `n` is less than the argument `nn`
 //    +1 if the subject `n` is greater than the argument `nn`
-func (n *Number) CompareNumber(kind NumberKind, nn Number) int {
+func (n *Number) CompareNumber(kind Kind, nn Number) int {
 	switch kind {
-	case Int64NumberKind:
+	case Int64Kind:
 		return n.CompareInt64(nn.AsInt64())
-	case Float64NumberKind:
+	case Float64Kind:
 		return n.CompareFloat64(nn.AsFloat64())
 	default:
 		// you get what you deserve
@@ -443,7 +441,7 @@ func (n *Number) CompareNumber(kind NumberKind, nn Number) int {
 
 // CompareRaw compares two numbers, where one is input as a raw
 // uint64, interpreting both values as a `kind` of number.
-func (n *Number) CompareRaw(kind NumberKind, r uint64) int {
+func (n *Number) CompareRaw(kind Kind, r uint64) int {
 	return n.CompareNumber(kind, NewNumberFromRaw(r))
 }
 
@@ -482,17 +480,17 @@ func (n *Number) CompareFloat64(f float64) int {
 // - relations to zero
 
 // IsPositive returns true if the actual value is greater than zero.
-func (n *Number) IsPositive(kind NumberKind) bool {
+func (n *Number) IsPositive(kind Kind) bool {
 	return n.compareWithZero(kind) > 0
 }
 
 // IsNegative returns true if the actual value is less than zero.
-func (n *Number) IsNegative(kind NumberKind) bool {
+func (n *Number) IsNegative(kind Kind) bool {
 	return n.compareWithZero(kind) < 0
 }
 
 // IsZero returns true if the actual value is equal to zero.
-func (n *Number) IsZero(kind NumberKind) bool {
+func (n *Number) IsZero(kind Kind) bool {
 	return n.compareWithZero(kind) == 0
 }
 
@@ -501,11 +499,11 @@ func (n *Number) IsZero(kind NumberKind) bool {
 // Emit returns a string representation of the raw value of the
 // Number. A %d is used for integral values, %f for floating point
 // values.
-func (n *Number) Emit(kind NumberKind) string {
+func (n *Number) Emit(kind Kind) string {
 	switch kind {
-	case Int64NumberKind:
+	case Int64Kind:
 		return fmt.Sprintf("%d", n.AsInt64())
-	case Float64NumberKind:
+	case Float64Kind:
 		return fmt.Sprintf("%f", n.AsFloat64())
 	default:
 		return ""
@@ -513,12 +511,12 @@ func (n *Number) Emit(kind NumberKind) string {
 }
 
 // AsInterface returns the number as an interface{}, typically used
-// for NumberKind-correct JSON conversion.
-func (n *Number) AsInterface(kind NumberKind) interface{} {
+// for Kind-correct JSON conversion.
+func (n *Number) AsInterface(kind Kind) interface{} {
 	switch kind {
-	case Int64NumberKind:
+	case Int64Kind:
 		return n.AsInt64()
-	case Float64NumberKind:
+	case Float64Kind:
 		return n.AsFloat64()
 	default:
 		return math.NaN()
@@ -527,11 +525,11 @@ func (n *Number) AsInterface(kind NumberKind) interface{} {
 
 // - private stuff
 
-func (n *Number) compareWithZero(kind NumberKind) int {
+func (n *Number) compareWithZero(kind Kind) int {
 	switch kind {
-	case Int64NumberKind:
+	case Int64Kind:
 		return n.CompareInt64(0)
-	case Float64NumberKind:
+	case Float64Kind:
 		return n.CompareFloat64(0.)
 	default:
 		// you get what you deserve
diff --git a/registry/registry.go b/metric/registry/registry.go
similarity index 98%
rename from registry/registry.go
rename to metric/registry/registry.go
index 3e845e70..244ae5dc 100644
--- a/registry/registry.go
+++ b/metric/registry/registry.go
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package registry // import "go.opentelemetry.io/otel/registry"
+package registry // import "go.opentelemetry.io/otel/metric/registry"
 
 import (
 	"context"
diff --git a/metric_instrument.go b/metric_instrument.go
index a9f75646..608e4995 100644
--- a/metric_instrument.go
+++ b/metric_instrument.go
@@ -21,6 +21,7 @@ import (
 	"errors"
 
 	"go.opentelemetry.io/otel/label"
+	"go.opentelemetry.io/otel/metric/number"
 )
 
 // ErrSDKReturnedNilImpl is returned when a new `MeterImpl` returns nil.
@@ -94,7 +95,7 @@ func (k InstrumentKind) PrecomputedSum() bool {
 // instruments (e.g., Int64ValueObserver.Observation()).
 type Observation struct {
 	// number needs to be aligned for 64-bit atomic operations.
-	number     Number
+	number     number.Number
 	instrument AsyncImpl
 }
 
@@ -136,7 +137,7 @@ type BatchObserverResult struct {
 func (ir Int64ObserverResult) Observe(value int64, labels ...label.KeyValue) {
 	ir.function(labels, Observation{
 		instrument: ir.instrument,
-		number:     NewInt64Number(value),
+		number:     number.NewInt64Number(value),
 	})
 }
 
@@ -145,7 +146,7 @@ func (ir Int64ObserverResult) Observe(value int64, labels ...label.KeyValue) {
 func (fr Float64ObserverResult) Observe(value float64, labels ...label.KeyValue) {
 	fr.function(labels, Observation{
 		instrument: fr.instrument,
-		number:     NewFloat64Number(value),
+		number:     number.NewFloat64Number(value),
 	})
 }
 
@@ -323,7 +324,7 @@ type Float64UpDownSumObserver struct {
 // users should not refer to this.
 func (i Int64ValueObserver) Observation(v int64) Observation {
 	return Observation{
-		number:     NewInt64Number(v),
+		number:     number.NewInt64Number(v),
 		instrument: i.instrument,
 	}
 }
@@ -334,7 +335,7 @@ func (i Int64ValueObserver) Observation(v int64) Observation {
 // users should not refer to this.
 func (f Float64ValueObserver) Observation(v float64) Observation {
 	return Observation{
-		number:     NewFloat64Number(v),
+		number:     number.NewFloat64Number(v),
 		instrument: f.instrument,
 	}
 }
@@ -345,7 +346,7 @@ func (f Float64ValueObserver) Observation(v float64) Observation {
 // users should not refer to this.
 func (i Int64SumObserver) Observation(v int64) Observation {
 	return Observation{
-		number:     NewInt64Number(v),
+		number:     number.NewInt64Number(v),
 		instrument: i.instrument,
 	}
 }
@@ -356,7 +357,7 @@ func (i Int64SumObserver) Observation(v int64) Observation {
 // users should not refer to this.
 func (f Float64SumObserver) Observation(v float64) Observation {
 	return Observation{
-		number:     NewFloat64Number(v),
+		number:     number.NewFloat64Number(v),
 		instrument: f.instrument,
 	}
 }
@@ -367,7 +368,7 @@ func (f Float64SumObserver) Observation(v float64) Observation {
 // users should not refer to this.
 func (i Int64UpDownSumObserver) Observation(v int64) Observation {
 	return Observation{
-		number:     NewInt64Number(v),
+		number:     number.NewInt64Number(v),
 		instrument: i.instrument,
 	}
 }
@@ -378,7 +379,7 @@ func (i Int64UpDownSumObserver) Observation(v int64) Observation {
 // users should not refer to this.
 func (f Float64UpDownSumObserver) Observation(v float64) Observation {
 	return Observation{
-		number:     NewFloat64Number(v),
+		number:     number.NewFloat64Number(v),
 		instrument: f.instrument,
 	}
 }
@@ -388,7 +389,7 @@ func (f Float64UpDownSumObserver) Observation(v float64) Observation {
 // instruments (e.g., Int64Counter.Measurement()).
 type Measurement struct {
 	// number needs to be aligned for 64-bit atomic operations.
-	number     Number
+	number     number.Number
 	instrument SyncImpl
 }
 
@@ -415,7 +416,7 @@ func (m Measurement) SyncImpl() SyncImpl {
 }
 
 // Number returns a number recorded in this measurement.
-func (m Measurement) Number() Number {
+func (m Measurement) Number() number.Number {
 	return m.number
 }
 
@@ -427,7 +428,7 @@ func (m Observation) AsyncImpl() AsyncImpl {
 }
 
 // Number returns a number recorded in this observation.
-func (m Observation) Number() Number {
+func (m Observation) Number() number.Number {
 	return m.number
 }
 
@@ -446,18 +447,18 @@ func (s syncInstrument) bind(labels []label.KeyValue) syncBoundInstrument {
 }
 
 func (s syncInstrument) float64Measurement(value float64) Measurement {
-	return newMeasurement(s.instrument, NewFloat64Number(value))
+	return newMeasurement(s.instrument, number.NewFloat64Number(value))
 }
 
 func (s syncInstrument) int64Measurement(value int64) Measurement {
-	return newMeasurement(s.instrument, NewInt64Number(value))
+	return newMeasurement(s.instrument, number.NewInt64Number(value))
 }
 
-func (s syncInstrument) directRecord(ctx context.Context, number Number, labels []label.KeyValue) {
+func (s syncInstrument) directRecord(ctx context.Context, number number.Number, labels []label.KeyValue) {
 	s.instrument.RecordOne(ctx, number, labels)
 }
 
-func (h syncBoundInstrument) directRecord(ctx context.Context, number Number) {
+func (h syncBoundInstrument) directRecord(ctx context.Context, number number.Number) {
 	h.boundInstrument.RecordOne(ctx, number)
 }
 
@@ -507,7 +508,7 @@ func newSyncBoundInstrument(boundInstrument BoundSyncImpl) syncBoundInstrument {
 	}
 }
 
-func newMeasurement(instrument SyncImpl, number Number) Measurement {
+func newMeasurement(instrument SyncImpl, number number.Number) Measurement {
 	return Measurement{
 		instrument: instrument,
 		number:     number,
@@ -603,25 +604,25 @@ func (c Int64Counter) Measurement(value int64) Measurement {
 // Add adds the value to the counter's sum. The labels should contain
 // the keys and values to be associated with this value.
 func (c Float64Counter) Add(ctx context.Context, value float64, labels ...label.KeyValue) {
-	c.directRecord(ctx, NewFloat64Number(value), labels)
+	c.directRecord(ctx, number.NewFloat64Number(value), labels)
 }
 
 // Add adds the value to the counter's sum. The labels should contain
 // the keys and values to be associated with this value.
 func (c Int64Counter) Add(ctx context.Context, value int64, labels ...label.KeyValue) {
-	c.directRecord(ctx, NewInt64Number(value), labels)
+	c.directRecord(ctx, number.NewInt64Number(value), labels)
 }
 
 // Add adds the value to the counter's sum using the labels
 // previously bound to this counter via Bind()
 func (b BoundFloat64Counter) Add(ctx context.Context, value float64) {
-	b.directRecord(ctx, NewFloat64Number(value))
+	b.directRecord(ctx, number.NewFloat64Number(value))
 }
 
 // Add adds the value to the counter's sum using the labels
 // previously bound to this counter via Bind()
 func (b BoundInt64Counter) Add(ctx context.Context, value int64) {
-	b.directRecord(ctx, NewInt64Number(value))
+	b.directRecord(ctx, number.NewInt64Number(value))
 }
 
 // Float64UpDownCounter is a metric instrument that sums floating
@@ -678,25 +679,25 @@ func (c Int64UpDownCounter) Measurement(value int64) Measurement {
 // Add adds the value to the counter's sum. The labels should contain
 // the keys and values to be associated with this value.
 func (c Float64UpDownCounter) Add(ctx context.Context, value float64, labels ...label.KeyValue) {
-	c.directRecord(ctx, NewFloat64Number(value), labels)
+	c.directRecord(ctx, number.NewFloat64Number(value), labels)
 }
 
 // Add adds the value to the counter's sum. The labels should contain
 // the keys and values to be associated with this value.
 func (c Int64UpDownCounter) Add(ctx context.Context, value int64, labels ...label.KeyValue) {
-	c.directRecord(ctx, NewInt64Number(value), labels)
+	c.directRecord(ctx, number.NewInt64Number(value), labels)
 }
 
 // Add adds the value to the counter's sum using the labels
 // previously bound to this counter via Bind()
 func (b BoundFloat64UpDownCounter) Add(ctx context.Context, value float64) {
-	b.directRecord(ctx, NewFloat64Number(value))
+	b.directRecord(ctx, number.NewFloat64Number(value))
 }
 
 // Add adds the value to the counter's sum using the labels
 // previously bound to this counter via Bind()
 func (b BoundInt64UpDownCounter) Add(ctx context.Context, value int64) {
-	b.directRecord(ctx, NewInt64Number(value))
+	b.directRecord(ctx, number.NewInt64Number(value))
 }
 
 // Float64ValueRecorder is a metric that records float64 values.
@@ -753,24 +754,24 @@ func (c Int64ValueRecorder) Measurement(value int64) Measurement {
 // labels should contain the keys and values to be associated with
 // this value.
 func (c Float64ValueRecorder) Record(ctx context.Context, value float64, labels ...label.KeyValue) {
-	c.directRecord(ctx, NewFloat64Number(value), labels)
+	c.directRecord(ctx, number.NewFloat64Number(value), labels)
 }
 
 // Record adds a new value to the ValueRecorder's distribution. The
 // labels should contain the keys and values to be associated with
 // this value.
 func (c Int64ValueRecorder) Record(ctx context.Context, value int64, labels ...label.KeyValue) {
-	c.directRecord(ctx, NewInt64Number(value), labels)
+	c.directRecord(ctx, number.NewInt64Number(value), labels)
 }
 
 // Record adds a new value to the ValueRecorder's distribution using the labels
 // previously bound to the ValueRecorder via Bind().
 func (b BoundFloat64ValueRecorder) Record(ctx context.Context, value float64) {
-	b.directRecord(ctx, NewFloat64Number(value))
+	b.directRecord(ctx, number.NewFloat64Number(value))
 }
 
 // Record adds a new value to the ValueRecorder's distribution using the labels
 // previously bound to the ValueRecorder via Bind().
 func (b BoundInt64ValueRecorder) Record(ctx context.Context, value int64) {
-	b.directRecord(ctx, NewInt64Number(value))
+	b.directRecord(ctx, number.NewInt64Number(value))
 }
diff --git a/metric_noop.go b/metric_noop.go
index 03273a9c..896139d8 100644
--- a/metric_noop.go
+++ b/metric_noop.go
@@ -18,6 +18,7 @@ import (
 	"context"
 
 	"go.opentelemetry.io/otel/label"
+	"go.opentelemetry.io/otel/metric/number"
 )
 
 type NoopMeterProvider struct{}
@@ -44,7 +45,7 @@ func (noopInstrument) Descriptor() Descriptor {
 	return Descriptor{}
 }
 
-func (noopBoundInstrument) RecordOne(context.Context, Number) {
+func (noopBoundInstrument) RecordOne(context.Context, number.Number) {
 }
 
 func (noopBoundInstrument) Unbind() {
@@ -54,5 +55,5 @@ func (NoopSync) Bind([]label.KeyValue) BoundSyncImpl {
 	return noopBoundInstrument{}
 }
 
-func (NoopSync) RecordOne(context.Context, Number, []label.KeyValue) {
+func (NoopSync) RecordOne(context.Context, number.Number, []label.KeyValue) {
 }
diff --git a/metric_sdkapi.go b/metric_sdkapi.go
index 73375f30..cc3d354c 100644
--- a/metric_sdkapi.go
+++ b/metric_sdkapi.go
@@ -18,6 +18,7 @@ import (
 	"context"
 
 	"go.opentelemetry.io/otel/label"
+	"go.opentelemetry.io/otel/metric/number"
 )
 
 // MeterImpl is the interface an SDK must implement to supply a Meter
@@ -62,7 +63,7 @@ type SyncImpl interface {
 	Bind(labels []label.KeyValue) BoundSyncImpl
 
 	// RecordOne captures a single synchronous metric event.
-	RecordOne(ctx context.Context, number Number, labels []label.KeyValue)
+	RecordOne(ctx context.Context, number number.Number, labels []label.KeyValue)
 }
 
 // BoundSyncImpl is the implementation-level interface to a
@@ -70,7 +71,7 @@ type SyncImpl interface {
 type BoundSyncImpl interface {
 
 	// RecordOne captures a single synchronous metric event.
-	RecordOne(ctx context.Context, number Number)
+	RecordOne(ctx context.Context, number number.Number)
 
 	// Unbind frees the resources associated with this bound instrument. It
 	// does not affect the metric this bound instrument was created through.
diff --git a/numberkind_string.go b/numberkind_string.go
deleted file mode 100644
index 005e324a..00000000
--- a/numberkind_string.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// Code generated by "stringer -type=NumberKind"; DO NOT EDIT.
-
-package otel
-
-import "strconv"
-
-func _() {
-	// An "invalid array index" compiler error signifies that the constant values have changed.
-	// Re-run the stringer command to generate them again.
-	var x [1]struct{}
-	_ = x[Int64NumberKind-0]
-	_ = x[Float64NumberKind-1]
-}
-
-const _NumberKind_name = "Int64NumberKindFloat64NumberKind"
-
-var _NumberKind_index = [...]uint8{0, 15, 32}
-
-func (i NumberKind) String() string {
-	if i < 0 || i >= NumberKind(len(_NumberKind_index)-1) {
-		return "NumberKind(" + strconv.FormatInt(int64(i), 10) + ")"
-	}
-	return _NumberKind_name[_NumberKind_index[i]:_NumberKind_index[i+1]]
-}
diff --git a/sdk/export/metric/aggregation/aggregation.go b/sdk/export/metric/aggregation/aggregation.go
index e81e9012..7f76b0ba 100644
--- a/sdk/export/metric/aggregation/aggregation.go
+++ b/sdk/export/metric/aggregation/aggregation.go
@@ -18,7 +18,7 @@ import (
 	"fmt"
 	"time"
 
-	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/metric/number"
 )
 
 // These interfaces describe the various ways to access state from an
@@ -37,7 +37,7 @@ type (
 	// Sum returns an aggregated sum.
 	Sum interface {
 		Aggregation
-		Sum() (otel.Number, error)
+		Sum() (number.Number, error)
 	}
 
 	// Count returns the number of values that were aggregated.
@@ -49,32 +49,32 @@ type (
 	// Min returns the minimum value over the set of values that were aggregated.
 	Min interface {
 		Aggregation
-		Min() (otel.Number, error)
+		Min() (number.Number, error)
 	}
 
 	// Max returns the maximum value over the set of values that were aggregated.
 	Max interface {
 		Aggregation
-		Max() (otel.Number, error)
+		Max() (number.Number, error)
 	}
 
 	// Quantile returns an exact or estimated quantile over the
 	// set of values that were aggregated.
 	Quantile interface {
 		Aggregation
-		Quantile(float64) (otel.Number, error)
+		Quantile(float64) (number.Number, error)
 	}
 
 	// LastValue returns the latest value that was aggregated.
 	LastValue interface {
 		Aggregation
-		LastValue() (otel.Number, time.Time, error)
+		LastValue() (number.Number, time.Time, error)
 	}
 
 	// Points returns the raw set of values that were aggregated.
 	Points interface {
 		Aggregation
-		Points() ([]otel.Number, error)
+		Points() ([]number.Number, error)
 	}
 
 	// Buckets represents histogram buckets boundaries and counts.
@@ -96,16 +96,16 @@ type (
 	Histogram interface {
 		Aggregation
 		Count() (int64, error)
-		Sum() (otel.Number, error)
+		Sum() (number.Number, error)
 		Histogram() (Buckets, error)
 	}
 
 	// MinMaxSumCount supports the Min, Max, Sum, and Count interfaces.
 	MinMaxSumCount interface {
 		Aggregation
-		Min() (otel.Number, error)
-		Max() (otel.Number, error)
-		Sum() (otel.Number, error)
+		Min() (number.Number, error)
+		Max() (number.Number, error)
+		Sum() (number.Number, error)
 		Count() (int64, error)
 	}
 
@@ -113,11 +113,11 @@ type (
 	// interfaces.
 	Distribution interface {
 		Aggregation
-		Min() (otel.Number, error)
-		Max() (otel.Number, error)
-		Sum() (otel.Number, error)
+		Min() (number.Number, error)
+		Max() (number.Number, error)
+		Sum() (number.Number, error)
 		Count() (int64, error)
-		Quantile(float64) (otel.Number, error)
+		Quantile(float64) (number.Number, error)
 	}
 )
 
diff --git a/sdk/export/metric/metric.go b/sdk/export/metric/metric.go
index a89a19db..1a55d738 100644
--- a/sdk/export/metric/metric.go
+++ b/sdk/export/metric/metric.go
@@ -23,6 +23,7 @@ import (
 
 	"go.opentelemetry.io/otel"
 	"go.opentelemetry.io/otel/label"
+	"go.opentelemetry.io/otel/metric/number"
 	"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
 	"go.opentelemetry.io/otel/sdk/resource"
 )
@@ -152,7 +153,7 @@ type Aggregator interface {
 	//
 	// The Context argument comes from user-level code and could be
 	// inspected for a `correlation.Map` or `trace.SpanContext`.
-	Update(ctx context.Context, number otel.Number, descriptor *otel.Descriptor) error
+	Update(ctx context.Context, number number.Number, descriptor *otel.Descriptor) error
 
 	// SynchronizedMove is called during collection to finish one
 	// period of aggregation by atomically saving the
diff --git a/sdk/metric/aggregator/aggregator.go b/sdk/metric/aggregator/aggregator.go
index 6393f42f..d024a9fd 100644
--- a/sdk/metric/aggregator/aggregator.go
+++ b/sdk/metric/aggregator/aggregator.go
@@ -19,6 +19,7 @@ import (
 	"math"
 
 	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/metric/number"
 	export "go.opentelemetry.io/otel/sdk/export/metric"
 	"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
 )
@@ -34,16 +35,16 @@ func NewInconsistentAggregatorError(a1, a2 export.Aggregator) error {
 // This rejects NaN values.  This rejects negative values when the
 // metric instrument does not support negative values, including
 // monotonic counter metrics and absolute ValueRecorder metrics.
-func RangeTest(number otel.Number, descriptor *otel.Descriptor) error {
+func RangeTest(num number.Number, descriptor *otel.Descriptor) error {
 	numberKind := descriptor.NumberKind()
 
-	if numberKind == otel.Float64NumberKind && math.IsNaN(number.AsFloat64()) {
+	if numberKind == number.Float64Kind && math.IsNaN(num.AsFloat64()) {
 		return aggregation.ErrNaNInput
 	}
 
 	switch descriptor.InstrumentKind() {
 	case otel.CounterInstrumentKind, otel.SumObserverInstrumentKind:
-		if number.IsNegative(numberKind) {
+		if num.IsNegative(numberKind) {
 			return aggregation.ErrNegativeInput
 		}
 	}
diff --git a/sdk/metric/aggregator/array/array.go b/sdk/metric/aggregator/array/array.go
index 5038aeed..fc14389a 100644
--- a/sdk/metric/aggregator/array/array.go
+++ b/sdk/metric/aggregator/array/array.go
@@ -22,6 +22,7 @@ import (
 	"unsafe"
 
 	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/metric/number"
 	export "go.opentelemetry.io/otel/sdk/export/metric"
 	"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
 	"go.opentelemetry.io/otel/sdk/metric/aggregator"
@@ -32,11 +33,11 @@ type (
 	// an array with the exact set of values.
 	Aggregator struct {
 		lock   sync.Mutex
-		sum    otel.Number
+		sum    number.Number
 		points points
 	}
 
-	points []otel.Number
+	points []number.Number
 )
 
 var _ export.Aggregator = &Aggregator{}
@@ -62,7 +63,7 @@ func (c *Aggregator) Kind() aggregation.Kind {
 }
 
 // Sum returns the sum of values in the checkpoint.
-func (c *Aggregator) Sum() (otel.Number, error) {
+func (c *Aggregator) Sum() (number.Number, error) {
 	return c.sum, nil
 }
 
@@ -72,23 +73,23 @@ func (c *Aggregator) Count() (int64, error) {
 }
 
 // Max returns the maximum value in the checkpoint.
-func (c *Aggregator) Max() (otel.Number, error) {
+func (c *Aggregator) Max() (number.Number, error) {
 	return c.points.Quantile(1)
 }
 
 // Min returns the mininum value in the checkpoint.
-func (c *Aggregator) Min() (otel.Number, error) {
+func (c *Aggregator) Min() (number.Number, error) {
 	return c.points.Quantile(0)
 }
 
 // Quantile returns the estimated quantile of data in the checkpoint.
 // It is an error if `q` is less than 0 or greated than 1.
-func (c *Aggregator) Quantile(q float64) (otel.Number, error) {
+func (c *Aggregator) Quantile(q float64) (number.Number, error) {
 	return c.points.Quantile(q)
 }
 
 // Points returns access to the raw data set.
-func (c *Aggregator) Points() ([]otel.Number, error) {
+func (c *Aggregator) Points() ([]number.Number, error) {
 	return c.points, nil
 }
 
@@ -116,7 +117,7 @@ func (c *Aggregator) SynchronizedMove(oa export.Aggregator, desc *otel.Descripto
 // Update adds the recorded measurement to the current data set.
 // Update takes a lock to prevent concurrent Update() and SynchronizedMove()
 // calls.
-func (c *Aggregator) Update(_ context.Context, number otel.Number, desc *otel.Descriptor) error {
+func (c *Aggregator) Update(_ context.Context, number number.Number, desc *otel.Descriptor) error {
 	c.lock.Lock()
 	c.points = append(c.points, number)
 	c.sum.AddNumber(desc.NumberKind(), number)
@@ -140,12 +141,12 @@ func (c *Aggregator) Merge(oa export.Aggregator, desc *otel.Descriptor) error {
 	return nil
 }
 
-func (c *Aggregator) sort(kind otel.NumberKind) {
+func (c *Aggregator) sort(kind number.Kind) {
 	switch kind {
-	case otel.Float64NumberKind:
+	case number.Float64Kind:
 		sort.Float64s(*(*[]float64)(unsafe.Pointer(&c.points)))
 
-	case otel.Int64NumberKind:
+	case number.Int64Kind:
 		sort.Sort(&c.points)
 
 	default:
@@ -155,7 +156,7 @@ func (c *Aggregator) sort(kind otel.NumberKind) {
 	}
 }
 
-func combine(a, b points, kind otel.NumberKind) points {
+func combine(a, b points, kind number.Kind) points {
 	result := make(points, 0, len(a)+len(b))
 
 	for len(a) != 0 && len(b) != 0 {
@@ -190,7 +191,7 @@ func (p *points) Swap(i, j int) {
 // Quantile returns the least X such that Pr(x<X)>=q, where X is an
 // element of the data set.  This uses the "Nearest-Rank" definition
 // of a quantile.
-func (p *points) Quantile(q float64) (otel.Number, error) {
+func (p *points) Quantile(q float64) (number.Number, error) {
 	if len(*p) == 0 {
 		return 0, aggregation.ErrNoData
 	}
diff --git a/sdk/metric/aggregator/ddsketch/ddsketch.go b/sdk/metric/aggregator/ddsketch/ddsketch.go
index 6d35e3f2..0ef272b5 100644
--- a/sdk/metric/aggregator/ddsketch/ddsketch.go
+++ b/sdk/metric/aggregator/ddsketch/ddsketch.go
@@ -21,6 +21,7 @@ import (
 	sdk "github.com/DataDog/sketches-go/ddsketch"
 
 	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/metric/number"
 	export "go.opentelemetry.io/otel/sdk/export/metric"
 	"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
 	"go.opentelemetry.io/otel/sdk/metric/aggregator"
@@ -33,7 +34,7 @@ type Config = sdk.Config
 type Aggregator struct {
 	lock   sync.Mutex
 	cfg    *Config
-	kind   otel.NumberKind
+	kind   number.Kind
 	sketch *sdk.DDSketch
 }
 
@@ -73,7 +74,7 @@ func NewDefaultConfig() *Config {
 }
 
 // Sum returns the sum of values in the checkpoint.
-func (c *Aggregator) Sum() (otel.Number, error) {
+func (c *Aggregator) Sum() (number.Number, error) {
 	return c.toNumber(c.sketch.Sum()), nil
 }
 
@@ -83,18 +84,18 @@ func (c *Aggregator) Count() (int64, error) {
 }
 
 // Max returns the maximum value in the checkpoint.
-func (c *Aggregator) Max() (otel.Number, error) {
+func (c *Aggregator) Max() (number.Number, error) {
 	return c.Quantile(1)
 }
 
 // Min returns the minimum value in the checkpoint.
-func (c *Aggregator) Min() (otel.Number, error) {
+func (c *Aggregator) Min() (number.Number, error) {
 	return c.Quantile(0)
 }
 
 // Quantile returns the estimated quantile of data in the checkpoint.
 // It is an error if `q` is less than 0 or greated than 1.
-func (c *Aggregator) Quantile(q float64) (otel.Number, error) {
+func (c *Aggregator) Quantile(q float64) (number.Number, error) {
 	if c.sketch.Count() == 0 {
 		return 0, aggregation.ErrNoData
 	}
@@ -105,11 +106,11 @@ func (c *Aggregator) Quantile(q float64) (otel.Number, error) {
 	return c.toNumber(f), nil
 }
 
-func (c *Aggregator) toNumber(f float64) otel.Number {
-	if c.kind == otel.Float64NumberKind {
-		return otel.NewFloat64Number(f)
+func (c *Aggregator) toNumber(f float64) number.Number {
+	if c.kind == number.Float64Kind {
+		return number.NewFloat64Number(f)
 	}
-	return otel.NewInt64Number(int64(f))
+	return number.NewInt64Number(int64(f))
 }
 
 // SynchronizedMove saves the current state into oa and resets the current state to
@@ -131,7 +132,7 @@ func (c *Aggregator) SynchronizedMove(oa export.Aggregator, _ *otel.Descriptor)
 // Update adds the recorded measurement to the current data set.
 // Update takes a lock to prevent concurrent Update() and SynchronizedMove()
 // calls.
-func (c *Aggregator) Update(_ context.Context, number otel.Number, desc *otel.Descriptor) error {
+func (c *Aggregator) Update(_ context.Context, number number.Number, desc *otel.Descriptor) error {
 	c.lock.Lock()
 	defer c.lock.Unlock()
 	c.sketch.Add(number.CoerceToFloat64(desc.NumberKind()))
diff --git a/sdk/metric/aggregator/histogram/histogram.go b/sdk/metric/aggregator/histogram/histogram.go
index 2df53a4a..2eb6a3f0 100644
--- a/sdk/metric/aggregator/histogram/histogram.go
+++ b/sdk/metric/aggregator/histogram/histogram.go
@@ -20,6 +20,7 @@ import (
 	"sync"
 
 	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/metric/number"
 	export "go.opentelemetry.io/otel/sdk/export/metric"
 	"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
 	"go.opentelemetry.io/otel/sdk/metric/aggregator"
@@ -36,7 +37,7 @@ type (
 	Aggregator struct {
 		lock       sync.Mutex
 		boundaries []float64
-		kind       otel.NumberKind
+		kind       number.Kind
 		state      state
 	}
 
@@ -45,7 +46,7 @@ type (
 	// the less than equal bucket count for the pre-determined boundaries.
 	state struct {
 		bucketCounts []float64
-		sum          otel.Number
+		sum          number.Number
 		count        int64
 	}
 )
@@ -94,7 +95,7 @@ func (c *Aggregator) Kind() aggregation.Kind {
 }
 
 // Sum returns the sum of all values in the checkpoint.
-func (c *Aggregator) Sum() (otel.Number, error) {
+func (c *Aggregator) Sum() (number.Number, error) {
 	return c.state.sum, nil
 }
 
@@ -134,7 +135,7 @@ func emptyState(boundaries []float64) state {
 }
 
 // Update adds the recorded measurement to the current data set.
-func (c *Aggregator) Update(_ context.Context, number otel.Number, desc *otel.Descriptor) error {
+func (c *Aggregator) Update(_ context.Context, number number.Number, desc *otel.Descriptor) error {
 	kind := desc.NumberKind()
 	asFloat := number.CoerceToFloat64(kind)
 
diff --git a/sdk/metric/aggregator/lastvalue/lastvalue.go b/sdk/metric/aggregator/lastvalue/lastvalue.go
index c572090e..7e8b8bf6 100644
--- a/sdk/metric/aggregator/lastvalue/lastvalue.go
+++ b/sdk/metric/aggregator/lastvalue/lastvalue.go
@@ -21,6 +21,7 @@ import (
 	"unsafe"
 
 	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/metric/number"
 	export "go.opentelemetry.io/otel/sdk/export/metric"
 	"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
 	"go.opentelemetry.io/otel/sdk/metric/aggregator"
@@ -40,7 +41,7 @@ type (
 		// value is the int64- or float64-encoded Set() data
 		//
 		// value needs to be aligned for 64-bit atomic operations.
-		value otel.Number
+		value number.Number
 
 		// timestamp indicates when this record was submitted.
 		// this can be used to pick a winner when multiple
@@ -82,7 +83,7 @@ func (g *Aggregator) Kind() aggregation.Kind {
 // corresponding timestamp.  The error value aggregation.ErrNoData
 // will be returned if (due to a race condition) the checkpoint was
 // computed before the first value was set.
-func (g *Aggregator) LastValue() (otel.Number, time.Time, error) {
+func (g *Aggregator) LastValue() (number.Number, time.Time, error) {
 	gd := (*lastValueData)(g.value)
 	if gd == unsetLastValue {
 		return 0, time.Time{}, aggregation.ErrNoData
@@ -101,7 +102,7 @@ func (g *Aggregator) SynchronizedMove(oa export.Aggregator, _ *otel.Descriptor)
 }
 
 // Update atomically sets the current "last" value.
-func (g *Aggregator) Update(_ context.Context, number otel.Number, desc *otel.Descriptor) error {
+func (g *Aggregator) Update(_ context.Context, number number.Number, desc *otel.Descriptor) error {
 	ngd := &lastValueData{
 		value:     number,
 		timestamp: time.Now(),
diff --git a/sdk/metric/aggregator/minmaxsumcount/mmsc.go b/sdk/metric/aggregator/minmaxsumcount/mmsc.go
index 54db3a69..05848e3e 100644
--- a/sdk/metric/aggregator/minmaxsumcount/mmsc.go
+++ b/sdk/metric/aggregator/minmaxsumcount/mmsc.go
@@ -19,6 +19,7 @@ import (
 	"sync"
 
 	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/metric/number"
 	export "go.opentelemetry.io/otel/sdk/export/metric"
 	"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
 	"go.opentelemetry.io/otel/sdk/metric/aggregator"
@@ -29,14 +30,14 @@ type (
 	// keeping only the min, max, sum, and count.
 	Aggregator struct {
 		lock sync.Mutex
-		kind otel.NumberKind
+		kind number.Kind
 		state
 	}
 
 	state struct {
-		sum   otel.Number
-		min   otel.Number
-		max   otel.Number
+		sum   number.Number
+		min   number.Number
+		max   number.Number
 		count int64
 	}
 )
@@ -72,7 +73,7 @@ func (c *Aggregator) Kind() aggregation.Kind {
 }
 
 // Sum returns the sum of values in the checkpoint.
-func (c *Aggregator) Sum() (otel.Number, error) {
+func (c *Aggregator) Sum() (number.Number, error) {
 	return c.sum, nil
 }
 
@@ -84,7 +85,7 @@ func (c *Aggregator) Count() (int64, error) {
 // Min returns the minimum value in the checkpoint.
 // The error value aggregation.ErrNoData will be returned
 // if there were no measurements recorded during the checkpoint.
-func (c *Aggregator) Min() (otel.Number, error) {
+func (c *Aggregator) Min() (number.Number, error) {
 	if c.count == 0 {
 		return 0, aggregation.ErrNoData
 	}
@@ -94,7 +95,7 @@ func (c *Aggregator) Min() (otel.Number, error) {
 // Max returns the maximum value in the checkpoint.
 // The error value aggregation.ErrNoData will be returned
 // if there were no measurements recorded during the checkpoint.
-func (c *Aggregator) Max() (otel.Number, error) {
+func (c *Aggregator) Max() (number.Number, error) {
 	if c.count == 0 {
 		return 0, aggregation.ErrNoData
 	}
@@ -119,7 +120,7 @@ func (c *Aggregator) SynchronizedMove(oa export.Aggregator, desc *otel.Descripto
 	return nil
 }
 
-func emptyState(kind otel.NumberKind) state {
+func emptyState(kind number.Kind) state {
 	return state{
 		count: 0,
 		sum:   0,
@@ -129,7 +130,7 @@ func emptyState(kind otel.NumberKind) state {
 }
 
 // Update adds the recorded measurement to the current data set.
-func (c *Aggregator) Update(_ context.Context, number otel.Number, desc *otel.Descriptor) error {
+func (c *Aggregator) Update(_ context.Context, number number.Number, desc *otel.Descriptor) error {
 	kind := desc.NumberKind()
 
 	c.lock.Lock()
diff --git a/sdk/metric/aggregator/sum/sum.go b/sdk/metric/aggregator/sum/sum.go
index b1fbe050..d2fb44d4 100644
--- a/sdk/metric/aggregator/sum/sum.go
+++ b/sdk/metric/aggregator/sum/sum.go
@@ -18,6 +18,7 @@ import (
 	"context"
 
 	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/metric/number"
 	export "go.opentelemetry.io/otel/sdk/export/metric"
 	"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
 	"go.opentelemetry.io/otel/sdk/metric/aggregator"
@@ -27,7 +28,7 @@ import (
 type Aggregator struct {
 	// current holds current increments to this counter record
 	// current needs to be aligned for 64-bit atomic operations.
-	value otel.Number
+	value number.Number
 }
 
 var _ export.Aggregator = &Aggregator{}
@@ -53,7 +54,7 @@ func (c *Aggregator) Kind() aggregation.Kind {
 
 // Sum returns the last-checkpointed sum.  This will never return an
 // error.
-func (c *Aggregator) Sum() (otel.Number, error) {
+func (c *Aggregator) Sum() (number.Number, error) {
 	return c.value, nil
 }
 
@@ -64,13 +65,13 @@ func (c *Aggregator) SynchronizedMove(oa export.Aggregator, _ *otel.Descriptor)
 	if o == nil {
 		return aggregator.NewInconsistentAggregatorError(c, oa)
 	}
-	o.value = c.value.SwapNumberAtomic(otel.Number(0))
+	o.value = c.value.SwapNumberAtomic(number.Number(0))
 	return nil
 }
 
 // Update atomically adds to the current value.
-func (c *Aggregator) Update(_ context.Context, number otel.Number, desc *otel.Descriptor) error {
-	c.value.AddNumberAtomic(desc.NumberKind(), number)
+func (c *Aggregator) Update(_ context.Context, num number.Number, desc *otel.Descriptor) error {
+	c.value.AddNumberAtomic(desc.NumberKind(), num)
 	return nil
 }
 
@@ -96,6 +97,6 @@ func (c *Aggregator) Subtract(opAgg, resAgg export.Aggregator, descriptor *otel.
 	}
 
 	res.value = c.value
-	res.value.AddNumber(descriptor.NumberKind(), otel.NewNumberSignChange(descriptor.NumberKind(), op.value))
+	res.value.AddNumber(descriptor.NumberKind(), number.NewNumberSignChange(descriptor.NumberKind(), op.value))
 	return nil
 }
diff --git a/sdk/metric/controller/pull/pull.go b/sdk/metric/controller/pull/pull.go
index 8412075f..65ee4eae 100644
--- a/sdk/metric/controller/pull/pull.go
+++ b/sdk/metric/controller/pull/pull.go
@@ -19,7 +19,7 @@ import (
 	"time"
 
 	"go.opentelemetry.io/otel"
-	"go.opentelemetry.io/otel/registry"
+	"go.opentelemetry.io/otel/metric/registry"
 	export "go.opentelemetry.io/otel/sdk/export/metric"
 	sdk "go.opentelemetry.io/otel/sdk/metric"
 	controllerTime "go.opentelemetry.io/otel/sdk/metric/controller/time"
diff --git a/sdk/metric/controller/push/push.go b/sdk/metric/controller/push/push.go
index ccba41fa..f9f61e55 100644
--- a/sdk/metric/controller/push/push.go
+++ b/sdk/metric/controller/push/push.go
@@ -21,7 +21,7 @@ import (
 
 	"go.opentelemetry.io/otel"
 	"go.opentelemetry.io/otel/global"
-	"go.opentelemetry.io/otel/registry"
+	"go.opentelemetry.io/otel/metric/registry"
 	export "go.opentelemetry.io/otel/sdk/export/metric"
 	sdk "go.opentelemetry.io/otel/sdk/metric"
 	controllerTime "go.opentelemetry.io/otel/sdk/metric/controller/time"
diff --git a/sdk/metric/sdk.go b/sdk/metric/sdk.go
index 882382bc..e8258325 100644
--- a/sdk/metric/sdk.go
+++ b/sdk/metric/sdk.go
@@ -26,6 +26,7 @@ import (
 	"go.opentelemetry.io/otel/global"
 	internal "go.opentelemetry.io/otel/internal/metric"
 	"go.opentelemetry.io/otel/label"
+	"go.opentelemetry.io/otel/metric/number"
 	export "go.opentelemetry.io/otel/sdk/export/metric"
 	"go.opentelemetry.io/otel/sdk/metric/aggregator"
 	"go.opentelemetry.io/otel/sdk/resource"
@@ -162,8 +163,8 @@ func (s *syncInstrument) Implementation() interface{} {
 	return s
 }
 
-func (a *asyncInstrument) observe(number api.Number, labels *label.Set) {
-	if err := aggregator.RangeTest(number, &a.descriptor); err != nil {
+func (a *asyncInstrument) observe(num number.Number, labels *label.Set) {
+	if err := aggregator.RangeTest(num, &a.descriptor); err != nil {
 		global.Handle(err)
 		return
 	}
@@ -173,7 +174,7 @@ func (a *asyncInstrument) observe(number api.Number, labels *label.Set) {
 		// AggregatorSelector.
 		return
 	}
-	if err := recorder.Update(context.Background(), number, &a.descriptor); err != nil {
+	if err := recorder.Update(context.Background(), num, &a.descriptor); err != nil {
 		global.Handle(err)
 		return
 	}
@@ -290,10 +291,10 @@ func (s *syncInstrument) Bind(kvs []label.KeyValue) api.BoundSyncImpl {
 	return s.acquireHandle(kvs, nil)
 }
 
-func (s *syncInstrument) RecordOne(ctx context.Context, number api.Number, kvs []label.KeyValue) {
+func (s *syncInstrument) RecordOne(ctx context.Context, num number.Number, kvs []label.KeyValue) {
 	h := s.acquireHandle(kvs, nil)
 	defer h.Unbind()
-	h.RecordOne(ctx, number)
+	h.RecordOne(ctx, num)
 }
 
 // NewAccumulator constructs a new Accumulator for the given
@@ -501,16 +502,16 @@ func (m *Accumulator) RecordBatch(ctx context.Context, kvs []label.KeyValue, mea
 }
 
 // RecordOne implements api.SyncImpl.
-func (r *record) RecordOne(ctx context.Context, number api.Number) {
+func (r *record) RecordOne(ctx context.Context, num number.Number) {
 	if r.current == nil {
 		// The instrument is disabled according to the AggregatorSelector.
 		return
 	}
-	if err := aggregator.RangeTest(number, &r.inst.descriptor); err != nil {
+	if err := aggregator.RangeTest(num, &r.inst.descriptor); err != nil {
 		global.Handle(err)
 		return
 	}
-	if err := r.current.Update(ctx, number, &r.inst.descriptor); err != nil {
+	if err := r.current.Update(ctx, num, &r.inst.descriptor); err != nil {
 		global.Handle(err)
 		return
 	}


Test patch:
diff --git a/exporters/metric/prometheus/example_test.go b/exporters/metric/prometheus/example_test.go
index ac0c85a7..9f1da984 100644
--- a/exporters/metric/prometheus/example_test.go
+++ b/exporters/metric/prometheus/example_test.go
@@ -32,7 +32,7 @@ import (
 // This test demonstrates that it is relatively difficult to setup a
 // Prometheus export pipeline:
 //
-//   1. The default boundaries are difficult to pass, should be []float instead of []otel.Number
+//   1. The default boundaries are difficult to pass, should be []float instead of []number.Number
 //
 // TODO: Address this issue.
 
diff --git a/exporters/otlp/internal/transform/metric_test.go b/exporters/otlp/internal/transform/metric_test.go
index 2122ef3d..797e1fe6 100644
--- a/exporters/otlp/internal/transform/metric_test.go
+++ b/exporters/otlp/internal/transform/metric_test.go
@@ -24,11 +24,12 @@ import (
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 
-	"go.opentelemetry.io/otel"
 	commonpb "go.opentelemetry.io/otel/exporters/otlp/internal/opentelemetry-proto-gen/common/v1"
 	metricpb "go.opentelemetry.io/otel/exporters/otlp/internal/opentelemetry-proto-gen/metrics/v1"
 
+	"go.opentelemetry.io/otel"
 	"go.opentelemetry.io/otel/label"
+	"go.opentelemetry.io/otel/metric/number"
 	export "go.opentelemetry.io/otel/sdk/export/metric"
 	"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
 	"go.opentelemetry.io/otel/sdk/export/metric/metrictest"
@@ -114,15 +115,15 @@ func TestMinMaxSumCountValue(t *testing.T) {
 	require.NoError(t, mmsc.SynchronizedMove(ckpt, &otel.Descriptor{}))
 	min, max, sum, count, err := minMaxSumCountValues(ckpt.(aggregation.MinMaxSumCount))
 	if assert.NoError(t, err) {
-		assert.Equal(t, min, otel.NewInt64Number(1))
-		assert.Equal(t, max, otel.NewInt64Number(10))
-		assert.Equal(t, sum, otel.NewInt64Number(11))
+		assert.Equal(t, min, number.NewInt64Number(1))
+		assert.Equal(t, max, number.NewInt64Number(10))
+		assert.Equal(t, sum, number.NewInt64Number(11))
 		assert.Equal(t, count, int64(2))
 	}
 }
 
 func TestMinMaxSumCountDatapoints(t *testing.T) {
-	desc := otel.NewDescriptor("", otel.ValueRecorderInstrumentKind, otel.Int64NumberKind)
+	desc := otel.NewDescriptor("", otel.ValueRecorderInstrumentKind, number.Int64Kind)
 	labels := label.NewSet()
 	mmsc, ckpt := metrictest.Unslice2(minmaxsumcount.New(2, &desc))
 
@@ -161,10 +162,10 @@ func TestMinMaxSumCountPropagatesErrors(t *testing.T) {
 }
 
 func TestSumIntDataPoints(t *testing.T) {
-	desc := otel.NewDescriptor("", otel.ValueRecorderInstrumentKind, otel.Int64NumberKind)
+	desc := otel.NewDescriptor("", otel.ValueRecorderInstrumentKind, number.Int64Kind)
 	labels := label.NewSet()
 	s, ckpt := metrictest.Unslice2(sumAgg.New(2))
-	assert.NoError(t, s.Update(context.Background(), otel.Number(1), &desc))
+	assert.NoError(t, s.Update(context.Background(), number.Number(1), &desc))
 	require.NoError(t, s.SynchronizedMove(ckpt, &desc))
 	record := export.NewRecord(&desc, &labels, nil, ckpt.Aggregation(), intervalStart, intervalEnd)
 	sum, ok := ckpt.(aggregation.Sum)
@@ -189,10 +190,10 @@ func TestSumIntDataPoints(t *testing.T) {
 }
 
 func TestSumFloatDataPoints(t *testing.T) {
-	desc := otel.NewDescriptor("", otel.ValueRecorderInstrumentKind, otel.Float64NumberKind)
+	desc := otel.NewDescriptor("", otel.ValueRecorderInstrumentKind, number.Float64Kind)
 	labels := label.NewSet()
 	s, ckpt := metrictest.Unslice2(sumAgg.New(2))
-	assert.NoError(t, s.Update(context.Background(), otel.NewFloat64Number(1), &desc))
+	assert.NoError(t, s.Update(context.Background(), number.NewFloat64Number(1), &desc))
 	require.NoError(t, s.SynchronizedMove(ckpt, &desc))
 	record := export.NewRecord(&desc, &labels, nil, ckpt.Aggregation(), intervalStart, intervalEnd)
 	sum, ok := ckpt.(aggregation.Sum)
@@ -218,10 +219,10 @@ func TestSumFloatDataPoints(t *testing.T) {
 }
 
 func TestLastValueIntDataPoints(t *testing.T) {
-	desc := otel.NewDescriptor("", otel.ValueRecorderInstrumentKind, otel.Int64NumberKind)
+	desc := otel.NewDescriptor("", otel.ValueRecorderInstrumentKind, number.Int64Kind)
 	labels := label.NewSet()
 	s, ckpt := metrictest.Unslice2(lvAgg.New(2))
-	assert.NoError(t, s.Update(context.Background(), otel.Number(100), &desc))
+	assert.NoError(t, s.Update(context.Background(), number.Number(100), &desc))
 	require.NoError(t, s.SynchronizedMove(ckpt, &desc))
 	record := export.NewRecord(&desc, &labels, nil, ckpt.Aggregation(), intervalStart, intervalEnd)
 	sum, ok := ckpt.(aggregation.LastValue)
@@ -244,7 +245,7 @@ func TestLastValueIntDataPoints(t *testing.T) {
 }
 
 func TestSumErrUnknownValueType(t *testing.T) {
-	desc := otel.NewDescriptor("", otel.ValueRecorderInstrumentKind, otel.NumberKind(-1))
+	desc := otel.NewDescriptor("", otel.ValueRecorderInstrumentKind, number.Kind(-1))
 	labels := label.NewSet()
 	s := &sumAgg.New(1)[0]
 	record := export.NewRecord(&desc, &labels, nil, s, intervalStart, intervalEnd)
@@ -273,7 +274,7 @@ func (t *testAgg) Aggregation() aggregation.Aggregation {
 
 // None of these three are used:
 
-func (t *testAgg) Update(ctx context.Context, number otel.Number, descriptor *otel.Descriptor) error {
+func (t *testAgg) Update(ctx context.Context, number number.Number, descriptor *otel.Descriptor) error {
 	return nil
 }
 func (t *testAgg) SynchronizedMove(destination export.Aggregator, descriptor *otel.Descriptor) error {
@@ -295,25 +296,25 @@ type testErrMinMaxSumCount struct {
 	testErrSum
 }
 
-func (te *testErrLastValue) LastValue() (otel.Number, time.Time, error) {
+func (te *testErrLastValue) LastValue() (number.Number, time.Time, error) {
 	return 0, time.Time{}, te.err
 }
 func (te *testErrLastValue) Kind() aggregation.Kind {
 	return aggregation.LastValueKind
 }
 
-func (te *testErrSum) Sum() (otel.Number, error) {
+func (te *testErrSum) Sum() (number.Number, error) {
 	return 0, te.err
 }
 func (te *testErrSum) Kind() aggregation.Kind {
 	return aggregation.SumKind
 }
 
-func (te *testErrMinMaxSumCount) Min() (otel.Number, error) {
+func (te *testErrMinMaxSumCount) Min() (number.Number, error) {
 	return 0, te.err
 }
 
-func (te *testErrMinMaxSumCount) Max() (otel.Number, error) {
+func (te *testErrMinMaxSumCount) Max() (number.Number, error) {
 	return 0, te.err
 }
 
@@ -329,7 +330,7 @@ var _ aggregation.MinMaxSumCount = &testErrMinMaxSumCount{}
 
 func TestRecordAggregatorIncompatibleErrors(t *testing.T) {
 	makeMpb := func(kind aggregation.Kind, agg aggregation.Aggregation) (*metricpb.Metric, error) {
-		desc := otel.NewDescriptor("things", otel.CounterInstrumentKind, otel.Int64NumberKind)
+		desc := otel.NewDescriptor("things", otel.CounterInstrumentKind, number.Int64Kind)
 		labels := label.NewSet()
 		res := resource.Empty()
 		test := &testAgg{
@@ -366,7 +367,7 @@ func TestRecordAggregatorIncompatibleErrors(t *testing.T) {
 
 func TestRecordAggregatorUnexpectedErrors(t *testing.T) {
 	makeMpb := func(kind aggregation.Kind, agg aggregation.Aggregation) (*metricpb.Metric, error) {
-		desc := otel.NewDescriptor("things", otel.CounterInstrumentKind, otel.Int64NumberKind)
+		desc := otel.NewDescriptor("things", otel.CounterInstrumentKind, number.Int64Kind)
 		labels := label.NewSet()
 		res := resource.Empty()
 		return Record(export.CumulativeExportKindSelector(), export.NewRecord(&desc, &labels, res, agg, intervalStart, intervalEnd))
diff --git a/exporters/otlp/otlp_integration_test.go b/exporters/otlp/otlp_integration_test.go
index 7999659e..de31aabe 100644
--- a/exporters/otlp/otlp_integration_test.go
+++ b/exporters/otlp/otlp_integration_test.go
@@ -25,11 +25,12 @@ import (
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 
-	"go.opentelemetry.io/otel"
 	commonpb "go.opentelemetry.io/otel/exporters/otlp/internal/opentelemetry-proto-gen/common/v1"
 	"go.opentelemetry.io/otel/label"
 
+	"go.opentelemetry.io/otel"
 	"go.opentelemetry.io/otel/exporters/otlp"
+	"go.opentelemetry.io/otel/metric/number"
 	metricsdk "go.opentelemetry.io/otel/sdk/export/metric"
 	exporttrace "go.opentelemetry.io/otel/sdk/export/trace"
 	"go.opentelemetry.io/otel/sdk/metric/controller/push"
@@ -130,47 +131,47 @@ func newExporterEndToEndTest(t *testing.T, additionalOpts []otlp.ExporterOption)
 
 	type data struct {
 		iKind otel.InstrumentKind
-		nKind otel.NumberKind
+		nKind number.Kind
 		val   int64
 	}
 	instruments := map[string]data{
-		"test-int64-counter":         {otel.CounterInstrumentKind, otel.Int64NumberKind, 1},
-		"test-float64-counter":       {otel.CounterInstrumentKind, otel.Float64NumberKind, 1},
-		"test-int64-valuerecorder":   {otel.ValueRecorderInstrumentKind, otel.Int64NumberKind, 2},
-		"test-float64-valuerecorder": {otel.ValueRecorderInstrumentKind, otel.Float64NumberKind, 2},
-		"test-int64-valueobserver":   {otel.ValueObserverInstrumentKind, otel.Int64NumberKind, 3},
-		"test-float64-valueobserver": {otel.ValueObserverInstrumentKind, otel.Float64NumberKind, 3},
+		"test-int64-counter":         {otel.CounterInstrumentKind, number.Int64Kind, 1},
+		"test-float64-counter":       {otel.CounterInstrumentKind, number.Float64Kind, 1},
+		"test-int64-valuerecorder":   {otel.ValueRecorderInstrumentKind, number.Int64Kind, 2},
+		"test-float64-valuerecorder": {otel.ValueRecorderInstrumentKind, number.Float64Kind, 2},
+		"test-int64-valueobserver":   {otel.ValueObserverInstrumentKind, number.Int64Kind, 3},
+		"test-float64-valueobserver": {otel.ValueObserverInstrumentKind, number.Float64Kind, 3},
 	}
 	for name, data := range instruments {
 		data := data
 		switch data.iKind {
 		case otel.CounterInstrumentKind:
 			switch data.nKind {
-			case otel.Int64NumberKind:
+			case number.Int64Kind:
 				otel.Must(meter).NewInt64Counter(name).Add(ctx, data.val, labels...)
-			case otel.Float64NumberKind:
+			case number.Float64Kind:
 				otel.Must(meter).NewFloat64Counter(name).Add(ctx, float64(data.val), labels...)
 			default:
 				assert.Failf(t, "unsupported number testing kind", data.nKind.String())
 			}
 		case otel.ValueRecorderInstrumentKind:
 			switch data.nKind {
-			case otel.Int64NumberKind:
+			case number.Int64Kind:
 				otel.Must(meter).NewInt64ValueRecorder(name).Record(ctx, data.val, labels...)
-			case otel.Float64NumberKind:
+			case number.Float64Kind:
 				otel.Must(meter).NewFloat64ValueRecorder(name).Record(ctx, float64(data.val), labels...)
 			default:
 				assert.Failf(t, "unsupported number testing kind", data.nKind.String())
 			}
 		case otel.ValueObserverInstrumentKind:
 			switch data.nKind {
-			case otel.Int64NumberKind:
+			case number.Int64Kind:
 				otel.Must(meter).NewInt64ValueObserver(name,
 					func(_ context.Context, result otel.Int64ObserverResult) {
 						result.Observe(data.val, labels...)
 					},
 				)
-			case otel.Float64NumberKind:
+			case number.Float64Kind:
 				callback := func(v float64) otel.Float64ObserverFunc {
 					return otel.Float64ObserverFunc(func(_ context.Context, result otel.Float64ObserverResult) { result.Observe(v, labels...) })
 				}(float64(data.val))
@@ -246,11 +247,11 @@ func newExporterEndToEndTest(t *testing.T, additionalOpts []otlp.ExporterOption)
 		switch data.iKind {
 		case otel.CounterInstrumentKind:
 			switch data.nKind {
-			case otel.Int64NumberKind:
+			case number.Int64Kind:
 				if dp := m.GetIntSum().DataPoints; assert.Len(t, dp, 1) {
 					assert.Equal(t, data.val, dp[0].Value, "invalid value for %q", m.Name)
 				}
-			case otel.Float64NumberKind:
+			case number.Float64Kind:
 				if dp := m.GetDoubleSum().DataPoints; assert.Len(t, dp, 1) {
 					assert.Equal(t, float64(data.val), dp[0].Value, "invalid value for %q", m.Name)
 				}
@@ -259,11 +260,11 @@ func newExporterEndToEndTest(t *testing.T, additionalOpts []otlp.ExporterOption)
 			}
 		case otel.ValueObserverInstrumentKind:
 			switch data.nKind {
-			case otel.Int64NumberKind:
+			case number.Int64Kind:
 				if dp := m.GetIntGauge().DataPoints; assert.Len(t, dp, 1) {
 					assert.Equal(t, data.val, dp[0].Value, "invalid value for %q", m.Name)
 				}
-			case otel.Float64NumberKind:
+			case number.Float64Kind:
 				if dp := m.GetDoubleGauge().DataPoints; assert.Len(t, dp, 1) {
 					assert.Equal(t, float64(data.val), dp[0].Value, "invalid value for %q", m.Name)
 				}
@@ -272,14 +273,14 @@ func newExporterEndToEndTest(t *testing.T, additionalOpts []otlp.ExporterOption)
 			}
 		case otel.ValueRecorderInstrumentKind:
 			switch data.nKind {
-			case otel.Int64NumberKind:
+			case number.Int64Kind:
 				assert.NotNil(t, m.GetIntHistogram())
 				if dp := m.GetIntHistogram().DataPoints; assert.Len(t, dp, 1) {
 					count := dp[0].Count
 					assert.Equal(t, uint64(1), count, "invalid count for %q", m.Name)
 					assert.Equal(t, int64(data.val*int64(count)), dp[0].Sum, "invalid sum for %q (value %d)", m.Name, data.val)
 				}
-			case otel.Float64NumberKind:
+			case number.Float64Kind:
 				assert.NotNil(t, m.GetDoubleHistogram())
 				if dp := m.GetDoubleHistogram().DataPoints; assert.Len(t, dp, 1) {
 					count := dp[0].Count
diff --git a/exporters/otlp/otlp_metric_test.go b/exporters/otlp/otlp_metric_test.go
index 96d517b2..5ee32457 100644
--- a/exporters/otlp/otlp_metric_test.go
+++ b/exporters/otlp/otlp_metric_test.go
@@ -23,13 +23,14 @@ import (
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 
-	"go.opentelemetry.io/otel"
 	colmetricpb "go.opentelemetry.io/otel/exporters/otlp/internal/opentelemetry-proto-gen/collector/metrics/v1"
 	commonpb "go.opentelemetry.io/otel/exporters/otlp/internal/opentelemetry-proto-gen/common/v1"
 	metricpb "go.opentelemetry.io/otel/exporters/otlp/internal/opentelemetry-proto-gen/metrics/v1"
 	resourcepb "go.opentelemetry.io/otel/exporters/otlp/internal/opentelemetry-proto-gen/resource/v1"
 
+	"go.opentelemetry.io/otel"
 	"go.opentelemetry.io/otel/label"
+	"go.opentelemetry.io/otel/metric/number"
 	metricsdk "go.opentelemetry.io/otel/sdk/export/metric"
 	"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
 	"go.opentelemetry.io/otel/sdk/export/metric/metrictest"
@@ -94,7 +95,7 @@ func (m *checkpointSet) ForEach(_ metricsdk.ExportKindSelector, fn func(metricsd
 type record struct {
 	name     string
 	iKind    otel.InstrumentKind
-	nKind    otel.NumberKind
+	nKind    number.Kind
 	resource *resource.Resource
 	opts     []otel.InstrumentOption
 	labels   []label.KeyValue
@@ -164,7 +165,7 @@ func TestNoGroupingExport(t *testing.T) {
 			{
 				"int64-count",
 				otel.CounterInstrumentKind,
-				otel.Int64NumberKind,
+				number.Int64Kind,
 				nil,
 				nil,
 				append(baseKeyValues, cpuKey.Int(1)),
@@ -172,7 +173,7 @@ func TestNoGroupingExport(t *testing.T) {
 			{
 				"int64-count",
 				otel.CounterInstrumentKind,
-				otel.Int64NumberKind,
+				number.Int64Kind,
 				nil,
 				nil,
 				append(baseKeyValues, cpuKey.Int(2)),
@@ -219,7 +220,7 @@ func TestValuerecorderMetricGroupingExport(t *testing.T) {
 	r := record{
 		"valuerecorder",
 		otel.ValueRecorderInstrumentKind,
-		otel.Int64NumberKind,
+		number.Int64Kind,
 		nil,
 		nil,
 		append(baseKeyValues, cpuKey.Int(1)),
@@ -288,7 +289,7 @@ func TestCountInt64MetricGroupingExport(t *testing.T) {
 	r := record{
 		"int64-count",
 		otel.CounterInstrumentKind,
-		otel.Int64NumberKind,
+		number.Int64Kind,
 		nil,
 		nil,
 		append(baseKeyValues, cpuKey.Int(1)),
@@ -338,7 +339,7 @@ func TestCountFloat64MetricGroupingExport(t *testing.T) {
 	r := record{
 		"float64-count",
 		otel.CounterInstrumentKind,
-		otel.Float64NumberKind,
+		number.Float64Kind,
 		nil,
 		nil,
 		append(baseKeyValues, cpuKey.Int(1)),
@@ -410,7 +411,7 @@ func TestResourceMetricGroupingExport(t *testing.T) {
 			{
 				"int64-count",
 				otel.CounterInstrumentKind,
-				otel.Int64NumberKind,
+				number.Int64Kind,
 				testInstA,
 				nil,
 				append(baseKeyValues, cpuKey.Int(1)),
@@ -418,7 +419,7 @@ func TestResourceMetricGroupingExport(t *testing.T) {
 			{
 				"int64-count",
 				otel.CounterInstrumentKind,
-				otel.Int64NumberKind,
+				number.Int64Kind,
 				testInstA,
 				nil,
 				append(baseKeyValues, cpuKey.Int(1)),
@@ -426,7 +427,7 @@ func TestResourceMetricGroupingExport(t *testing.T) {
 			{
 				"int64-count",
 				otel.CounterInstrumentKind,
-				otel.Int64NumberKind,
+				number.Int64Kind,
 				testInstA,
 				nil,
 				append(baseKeyValues, cpuKey.Int(2)),
@@ -434,7 +435,7 @@ func TestResourceMetricGroupingExport(t *testing.T) {
 			{
 				"int64-count",
 				otel.CounterInstrumentKind,
-				otel.Int64NumberKind,
+				number.Int64Kind,
 				testInstB,
 				nil,
 				append(baseKeyValues, cpuKey.Int(1)),
@@ -528,7 +529,7 @@ func TestResourceInstLibMetricGroupingExport(t *testing.T) {
 			{
 				"int64-count",
 				otel.CounterInstrumentKind,
-				otel.Int64NumberKind,
+				number.Int64Kind,
 				testInstA,
 				countingLib1,
 				append(baseKeyValues, cpuKey.Int(1)),
@@ -536,7 +537,7 @@ func TestResourceInstLibMetricGroupingExport(t *testing.T) {
 			{
 				"int64-count",
 				otel.CounterInstrumentKind,
-				otel.Int64NumberKind,
+				number.Int64Kind,
 				testInstA,
 				countingLib2,
 				append(baseKeyValues, cpuKey.Int(1)),
@@ -544,7 +545,7 @@ func TestResourceInstLibMetricGroupingExport(t *testing.T) {
 			{
 				"int64-count",
 				otel.CounterInstrumentKind,
-				otel.Int64NumberKind,
+				number.Int64Kind,
 				testInstA,
 				countingLib1,
 				append(baseKeyValues, cpuKey.Int(1)),
@@ -552,7 +553,7 @@ func TestResourceInstLibMetricGroupingExport(t *testing.T) {
 			{
 				"int64-count",
 				otel.CounterInstrumentKind,
-				otel.Int64NumberKind,
+				number.Int64Kind,
 				testInstA,
 				countingLib1,
 				append(baseKeyValues, cpuKey.Int(2)),
@@ -560,7 +561,7 @@ func TestResourceInstLibMetricGroupingExport(t *testing.T) {
 			{
 				"int64-count",
 				otel.CounterInstrumentKind,
-				otel.Int64NumberKind,
+				number.Int64Kind,
 				testInstA,
 				summingLib,
 				append(baseKeyValues, cpuKey.Int(1)),
@@ -568,7 +569,7 @@ func TestResourceInstLibMetricGroupingExport(t *testing.T) {
 			{
 				"int64-count",
 				otel.CounterInstrumentKind,
-				otel.Int64NumberKind,
+				number.Int64Kind,
 				testInstB,
 				countingLib1,
 				append(baseKeyValues, cpuKey.Int(1)),
@@ -726,7 +727,7 @@ func TestStatelessExportKind(t *testing.T) {
 					{
 						"instrument",
 						k.instrumentKind,
-						otel.Int64NumberKind,
+						number.Int64Kind,
 						testInstA,
 						nil,
 						append(baseKeyValues, cpuKey.Int(1)),
@@ -799,22 +800,22 @@ func runMetricExportTest(t *testing.T, exp *Exporter, rs []record, expected []me
 		if r.iKind.Synchronous() {
 			// For synchronous instruments, perform two updates: 1 and 10
 			switch r.nKind {
-			case otel.Int64NumberKind:
-				require.NoError(t, agg.Update(ctx, otel.NewInt64Number(1), &desc))
-				require.NoError(t, agg.Update(ctx, otel.NewInt64Number(10), &desc))
-			case otel.Float64NumberKind:
-				require.NoError(t, agg.Update(ctx, otel.NewFloat64Number(1), &desc))
-				require.NoError(t, agg.Update(ctx, otel.NewFloat64Number(10), &desc))
+			case number.Int64Kind:
+				require.NoError(t, agg.Update(ctx, number.NewInt64Number(1), &desc))
+				require.NoError(t, agg.Update(ctx, number.NewInt64Number(10), &desc))
+			case number.Float64Kind:
+				require.NoError(t, agg.Update(ctx, number.NewFloat64Number(1), &desc))
+				require.NoError(t, agg.Update(ctx, number.NewFloat64Number(10), &desc))
 			default:
 				t.Fatalf("invalid number kind: %v", r.nKind)
 			}
 		} else {
 			// For asynchronous instruments, perform a single update: 11
 			switch r.nKind {
-			case otel.Int64NumberKind:
-				require.NoError(t, agg.Update(ctx, otel.NewInt64Number(11), &desc))
-			case otel.Float64NumberKind:
-				require.NoError(t, agg.Update(ctx, otel.NewFloat64Number(11), &desc))
+			case number.Int64Kind:
+				require.NoError(t, agg.Update(ctx, number.NewInt64Number(11), &desc))
+			case number.Float64Kind:
+				require.NoError(t, agg.Update(ctx, number.NewFloat64Number(11), &desc))
 			default:
 				t.Fatalf("invalid number kind: %v", r.nKind)
 			}
diff --git a/exporters/stdout/metric_test.go b/exporters/stdout/metric_test.go
index 33c2c02e..f75b69af 100644
--- a/exporters/stdout/metric_test.go
+++ b/exporters/stdout/metric_test.go
@@ -29,6 +29,7 @@ import (
 	"go.opentelemetry.io/otel"
 	"go.opentelemetry.io/otel/exporters/stdout"
 	"go.opentelemetry.io/otel/label"
+	"go.opentelemetry.io/otel/metric/number"
 	export "go.opentelemetry.io/otel/sdk/export/metric"
 	"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
 	"go.opentelemetry.io/otel/sdk/export/metric/metrictest"
@@ -99,11 +100,11 @@ func TestStdoutTimestamp(t *testing.T) {
 	checkpointSet := metrictest.NewCheckpointSet(testResource)
 
 	ctx := context.Background()
-	desc := otel.NewDescriptor("test.name", otel.ValueObserverInstrumentKind, otel.Int64NumberKind)
+	desc := otel.NewDescriptor("test.name", otel.ValueObserverInstrumentKind, number.Int64Kind)
 
 	lvagg, ckpt := metrictest.Unslice2(lastvalue.New(2))
 
-	aggregatortest.CheckedUpdate(t, lvagg, otel.NewInt64Number(321), &desc)
+	aggregatortest.CheckedUpdate(t, lvagg, number.NewInt64Number(321), &desc)
 	require.NoError(t, lvagg.SynchronizedMove(ckpt, &desc))
 
 	checkpointSet.Add(&desc, ckpt)
@@ -138,11 +139,11 @@ func TestStdoutCounterFormat(t *testing.T) {
 
 	checkpointSet := metrictest.NewCheckpointSet(testResource)
 
-	desc := otel.NewDescriptor("test.name", otel.CounterInstrumentKind, otel.Int64NumberKind)
+	desc := otel.NewDescriptor("test.name", otel.CounterInstrumentKind, number.Int64Kind)
 
 	cagg, ckpt := metrictest.Unslice2(sum.New(2))
 
-	aggregatortest.CheckedUpdate(fix.t, cagg, otel.NewInt64Number(123), &desc)
+	aggregatortest.CheckedUpdate(fix.t, cagg, number.NewInt64Number(123), &desc)
 	require.NoError(t, cagg.SynchronizedMove(ckpt, &desc))
 
 	checkpointSet.Add(&desc, ckpt, label.String("A", "B"), label.String("C", "D"))
@@ -157,10 +158,10 @@ func TestStdoutLastValueFormat(t *testing.T) {
 
 	checkpointSet := metrictest.NewCheckpointSet(testResource)
 
-	desc := otel.NewDescriptor("test.name", otel.ValueObserverInstrumentKind, otel.Float64NumberKind)
+	desc := otel.NewDescriptor("test.name", otel.ValueObserverInstrumentKind, number.Float64Kind)
 	lvagg, ckpt := metrictest.Unslice2(lastvalue.New(2))
 
-	aggregatortest.CheckedUpdate(fix.t, lvagg, otel.NewFloat64Number(123.456), &desc)
+	aggregatortest.CheckedUpdate(fix.t, lvagg, number.NewFloat64Number(123.456), &desc)
 	require.NoError(t, lvagg.SynchronizedMove(ckpt, &desc))
 
 	checkpointSet.Add(&desc, ckpt, label.String("A", "B"), label.String("C", "D"))
@@ -175,12 +176,12 @@ func TestStdoutMinMaxSumCount(t *testing.T) {
 
 	checkpointSet := metrictest.NewCheckpointSet(testResource)
 
-	desc := otel.NewDescriptor("test.name", otel.ValueRecorderInstrumentKind, otel.Float64NumberKind)
+	desc := otel.NewDescriptor("test.name", otel.ValueRecorderInstrumentKind, number.Float64Kind)
 
 	magg, ckpt := metrictest.Unslice2(minmaxsumcount.New(2, &desc))
 
-	aggregatortest.CheckedUpdate(fix.t, magg, otel.NewFloat64Number(123.456), &desc)
-	aggregatortest.CheckedUpdate(fix.t, magg, otel.NewFloat64Number(876.543), &desc)
+	aggregatortest.CheckedUpdate(fix.t, magg, number.NewFloat64Number(123.456), &desc)
+	aggregatortest.CheckedUpdate(fix.t, magg, number.NewFloat64Number(876.543), &desc)
 	require.NoError(t, magg.SynchronizedMove(ckpt, &desc))
 
 	checkpointSet.Add(&desc, ckpt, label.String("A", "B"), label.String("C", "D"))
@@ -195,11 +196,11 @@ func TestStdoutValueRecorderFormat(t *testing.T) {
 
 	checkpointSet := metrictest.NewCheckpointSet(testResource)
 
-	desc := otel.NewDescriptor("test.name", otel.ValueRecorderInstrumentKind, otel.Float64NumberKind)
+	desc := otel.NewDescriptor("test.name", otel.ValueRecorderInstrumentKind, number.Float64Kind)
 	aagg, ckpt := metrictest.Unslice2(array.New(2))
 
 	for i := 0; i < 1000; i++ {
-		aggregatortest.CheckedUpdate(fix.t, aagg, otel.NewFloat64Number(float64(i)+0.5), &desc)
+		aggregatortest.CheckedUpdate(fix.t, aagg, number.NewFloat64Number(float64(i)+0.5), &desc)
 	}
 
 	require.NoError(t, aagg.SynchronizedMove(ckpt, &desc))
@@ -234,7 +235,7 @@ func TestStdoutValueRecorderFormat(t *testing.T) {
 }
 
 func TestStdoutNoData(t *testing.T) {
-	desc := otel.NewDescriptor("test.name", otel.ValueRecorderInstrumentKind, otel.Float64NumberKind)
+	desc := otel.NewDescriptor("test.name", otel.ValueRecorderInstrumentKind, number.Float64Kind)
 
 	runTwoAggs := func(agg, ckpt export.Aggregator) {
 		t.Run(fmt.Sprintf("%T", agg), func(t *testing.T) {
@@ -263,7 +264,7 @@ func TestStdoutLastValueNotSet(t *testing.T) {
 
 	checkpointSet := metrictest.NewCheckpointSet(testResource)
 
-	desc := otel.NewDescriptor("test.name", otel.ValueObserverInstrumentKind, otel.Float64NumberKind)
+	desc := otel.NewDescriptor("test.name", otel.ValueObserverInstrumentKind, number.Float64Kind)
 
 	lvagg, ckpt := metrictest.Unslice2(lastvalue.New(2))
 	require.NoError(t, lvagg.SynchronizedMove(ckpt, &desc))
@@ -314,10 +315,10 @@ func TestStdoutResource(t *testing.T) {
 
 		checkpointSet := metrictest.NewCheckpointSet(tc.res)
 
-		desc := otel.NewDescriptor("test.name", otel.ValueObserverInstrumentKind, otel.Float64NumberKind)
+		desc := otel.NewDescriptor("test.name", otel.ValueObserverInstrumentKind, number.Float64Kind)
 		lvagg, ckpt := metrictest.Unslice2(lastvalue.New(2))
 
-		aggregatortest.CheckedUpdate(fix.t, lvagg, otel.NewFloat64Number(123.456), &desc)
+		aggregatortest.CheckedUpdate(fix.t, lvagg, number.NewFloat64Number(123.456), &desc)
 		require.NoError(t, lvagg.SynchronizedMove(ckpt, &desc))
 
 		checkpointSet.Add(&desc, ckpt, tc.attrs...)
diff --git a/global/internal/meter_test.go b/global/internal/meter_test.go
index 7c7b887c..4c55a119 100644
--- a/global/internal/meter_test.go
+++ b/global/internal/meter_test.go
@@ -25,13 +25,14 @@ import (
 	"go.opentelemetry.io/otel/global"
 	"go.opentelemetry.io/otel/global/internal"
 	"go.opentelemetry.io/otel/label"
+	"go.opentelemetry.io/otel/metric/number"
 	"go.opentelemetry.io/otel/oteltest"
 )
 
 var Must = otel.Must
 
-var asInt = otel.NewInt64Number
-var asFloat = otel.NewFloat64Number
+var asInt = number.NewInt64Number
+var asFloat = number.NewFloat64Number
 
 func TestDirect(t *testing.T) {
 	internal.ResetForTest()
diff --git a/global/internal/registry_test.go b/global/internal/registry_test.go
index 42f0aec0..c2a597b5 100644
--- a/global/internal/registry_test.go
+++ b/global/internal/registry_test.go
@@ -22,7 +22,7 @@ import (
 	"github.com/stretchr/testify/require"
 
 	"go.opentelemetry.io/otel"
-	"go.opentelemetry.io/otel/registry"
+	"go.opentelemetry.io/otel/metric/registry"
 )
 
 type (
diff --git a/number_test.go b/metric/number/number_test.go
similarity index 79%
rename from number_test.go
rename to metric/number/number_test.go
index 6c11e95a..e8d675c7 100644
--- a/number_test.go
+++ b/metric/number/number_test.go
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package otel
+package number
 
 import (
 	"math"
@@ -31,7 +31,7 @@ func TestNumber(t *testing.T) {
 	for idx, i := range []int64{-42, 0, 42} {
 		n := i64Numbers[idx]
 		if got := n.AsInt64(); got != i {
-			t.Errorf("Number %#v (%s) int64 check failed, expected %d, got %d", n, n.Emit(Int64NumberKind), i, got)
+			t.Errorf("Number %#v (%s) int64 check failed, expected %d, got %d", n, n.Emit(Int64Kind), i, got)
 		}
 	}
 
@@ -51,7 +51,7 @@ func TestNumber(t *testing.T) {
 	for idx, f := range []float64{-42., 0., 42.} {
 		n := f64Numbers[idx]
 		if got := n.AsFloat64(); got != f {
-			t.Errorf("Number %#v (%s) float64 check failed, expected %f, got %f", n, n.Emit(Int64NumberKind), f, got)
+			t.Errorf("Number %#v (%s) float64 check failed, expected %f, got %f", n, n.Emit(Int64Kind), f, got)
 		}
 	}
 
@@ -72,7 +72,7 @@ func TestNumber(t *testing.T) {
 		n Number
 		// nums needs to be aligned for 64-bit atomic operations.
 		nums [3]Number
-		kind NumberKind
+		kind Kind
 		pos  bool
 		zero bool
 		neg  bool
@@ -81,7 +81,7 @@ func TestNumber(t *testing.T) {
 	testcases := []testcase{
 		{
 			n:    iNeg,
-			kind: Int64NumberKind,
+			kind: Int64Kind,
 			pos:  false,
 			zero: false,
 			neg:  true,
@@ -90,7 +90,7 @@ func TestNumber(t *testing.T) {
 		},
 		{
 			n:    iZero,
-			kind: Int64NumberKind,
+			kind: Int64Kind,
 			pos:  false,
 			zero: true,
 			neg:  false,
@@ -99,7 +99,7 @@ func TestNumber(t *testing.T) {
 		},
 		{
 			n:    iPos,
-			kind: Int64NumberKind,
+			kind: Int64Kind,
 			pos:  true,
 			zero: false,
 			neg:  false,
@@ -108,7 +108,7 @@ func TestNumber(t *testing.T) {
 		},
 		{
 			n:    fNeg,
-			kind: Float64NumberKind,
+			kind: Float64Kind,
 			pos:  false,
 			zero: false,
 			neg:  true,
@@ -117,7 +117,7 @@ func TestNumber(t *testing.T) {
 		},
 		{
 			n:    fZero,
-			kind: Float64NumberKind,
+			kind: Float64Kind,
 			pos:  false,
 			zero: true,
 			neg:  false,
@@ -126,7 +126,7 @@ func TestNumber(t *testing.T) {
 		},
 		{
 			n:    fPos,
-			kind: Float64NumberKind,
+			kind: Float64Kind,
 			pos:  true,
 			zero: false,
 			neg:  false,
@@ -165,8 +165,8 @@ func TestNumberZero(t *testing.T) {
 func TestNumberAsInterface(t *testing.T) {
 	i64 := NewInt64Number(10)
 	f64 := NewFloat64Number(11.11)
-	require.Equal(t, int64(10), (&i64).AsInterface(Int64NumberKind).(int64))
-	require.Equal(t, 11.11, (&f64).AsInterface(Float64NumberKind).(float64))
+	require.Equal(t, int64(10), (&i64).AsInterface(Int64Kind).(int64))
+	require.Equal(t, 11.11, (&f64).AsInterface(Float64Kind).(float64))
 }
 
 func TestNumberSignChange(t *testing.T) {
@@ -174,39 +174,39 @@ func TestNumberSignChange(t *testing.T) {
 		posInt := NewInt64Number(10)
 		negInt := NewInt64Number(-10)
 
-		require.Equal(t, posInt, NewNumberSignChange(Int64NumberKind, negInt))
-		require.Equal(t, negInt, NewNumberSignChange(Int64NumberKind, posInt))
+		require.Equal(t, posInt, NewNumberSignChange(Int64Kind, negInt))
+		require.Equal(t, negInt, NewNumberSignChange(Int64Kind, posInt))
 	})
 
 	t.Run("Float64", func(t *testing.T) {
 		posFloat := NewFloat64Number(10)
 		negFloat := NewFloat64Number(-10)
 
-		require.Equal(t, posFloat, NewNumberSignChange(Float64NumberKind, negFloat))
-		require.Equal(t, negFloat, NewNumberSignChange(Float64NumberKind, posFloat))
+		require.Equal(t, posFloat, NewNumberSignChange(Float64Kind, negFloat))
+		require.Equal(t, negFloat, NewNumberSignChange(Float64Kind, posFloat))
 	})
 
 	t.Run("Float64Zero", func(t *testing.T) {
 		posFloat := NewFloat64Number(0)
 		negFloat := NewFloat64Number(math.Copysign(0, -1))
 
-		require.Equal(t, posFloat, NewNumberSignChange(Float64NumberKind, negFloat))
-		require.Equal(t, negFloat, NewNumberSignChange(Float64NumberKind, posFloat))
+		require.Equal(t, posFloat, NewNumberSignChange(Float64Kind, negFloat))
+		require.Equal(t, negFloat, NewNumberSignChange(Float64Kind, posFloat))
 	})
 
 	t.Run("Float64Inf", func(t *testing.T) {
 		posFloat := NewFloat64Number(math.Inf(+1))
 		negFloat := NewFloat64Number(math.Inf(-1))
 
-		require.Equal(t, posFloat, NewNumberSignChange(Float64NumberKind, negFloat))
-		require.Equal(t, negFloat, NewNumberSignChange(Float64NumberKind, posFloat))
+		require.Equal(t, posFloat, NewNumberSignChange(Float64Kind, negFloat))
+		require.Equal(t, negFloat, NewNumberSignChange(Float64Kind, posFloat))
 	})
 
 	t.Run("Float64NaN", func(t *testing.T) {
 		posFloat := NewFloat64Number(math.NaN())
 		negFloat := NewFloat64Number(math.Copysign(math.NaN(), -1))
 
-		require.Equal(t, posFloat, NewNumberSignChange(Float64NumberKind, negFloat))
-		require.Equal(t, negFloat, NewNumberSignChange(Float64NumberKind, posFloat))
+		require.Equal(t, posFloat, NewNumberSignChange(Float64Kind, negFloat))
+		require.Equal(t, negFloat, NewNumberSignChange(Float64Kind, posFloat))
 	})
 }
diff --git a/registry/registry_test.go b/metric/registry/registry_test.go
similarity index 98%
rename from registry/registry_test.go
rename to metric/registry/registry_test.go
index 05084d96..024f13da 100644
--- a/registry/registry_test.go
+++ b/metric/registry/registry_test.go
@@ -22,8 +22,8 @@ import (
 	"github.com/stretchr/testify/require"
 
 	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/metric/registry"
 	"go.opentelemetry.io/otel/oteltest"
-	"go.opentelemetry.io/otel/registry"
 )
 
 type (
diff --git a/metric_test.go b/metric_test.go
index 3995a7b1..71a147db 100644
--- a/metric_test.go
+++ b/metric_test.go
@@ -21,6 +21,7 @@ import (
 
 	"go.opentelemetry.io/otel"
 	"go.opentelemetry.io/otel/label"
+	"go.opentelemetry.io/otel/metric/number"
 	"go.opentelemetry.io/otel/oteltest"
 	"go.opentelemetry.io/otel/unit"
 
@@ -118,7 +119,7 @@ func TestPrecomputedSum(t *testing.T) {
 	}
 }
 
-func checkSyncBatches(ctx context.Context, t *testing.T, labels []label.KeyValue, mock *oteltest.MeterImpl, nkind otel.NumberKind, mkind otel.InstrumentKind, instrument otel.InstrumentImpl, expected ...float64) {
+func checkSyncBatches(ctx context.Context, t *testing.T, labels []label.KeyValue, mock *oteltest.MeterImpl, nkind number.Kind, mkind otel.InstrumentKind, instrument otel.InstrumentImpl, expected ...float64) {
 	t.Helper()
 
 	batchesCount := len(mock.MeasurementBatches)
@@ -217,7 +218,7 @@ func TestCounter(t *testing.T) {
 		boundInstrument := c.Bind(labels...)
 		boundInstrument.Add(ctx, -742)
 		meter.RecordBatch(ctx, labels, c.Measurement(42))
-		checkSyncBatches(ctx, t, labels, mockSDK, otel.Float64NumberKind, otel.CounterInstrumentKind, c.SyncImpl(),
+		checkSyncBatches(ctx, t, labels, mockSDK, number.Float64Kind, otel.CounterInstrumentKind, c.SyncImpl(),
 			1994.1, -742, 42,
 		)
 	})
@@ -230,7 +231,7 @@ func TestCounter(t *testing.T) {
 		boundInstrument := c.Bind(labels...)
 		boundInstrument.Add(ctx, 4200)
 		meter.RecordBatch(ctx, labels, c.Measurement(420000))
-		checkSyncBatches(ctx, t, labels, mockSDK, otel.Int64NumberKind, otel.CounterInstrumentKind, c.SyncImpl(),
+		checkSyncBatches(ctx, t, labels, mockSDK, number.Int64Kind, otel.CounterInstrumentKind, c.SyncImpl(),
 			42, 4200, 420000,
 		)
 
@@ -244,7 +245,7 @@ func TestCounter(t *testing.T) {
 		boundInstrument := c.Bind(labels...)
 		boundInstrument.Add(ctx, -100)
 		meter.RecordBatch(ctx, labels, c.Measurement(42))
-		checkSyncBatches(ctx, t, labels, mockSDK, otel.Int64NumberKind, otel.UpDownCounterInstrumentKind, c.SyncImpl(),
+		checkSyncBatches(ctx, t, labels, mockSDK, number.Int64Kind, otel.UpDownCounterInstrumentKind, c.SyncImpl(),
 			100, -100, 42,
 		)
 	})
@@ -257,7 +258,7 @@ func TestCounter(t *testing.T) {
 		boundInstrument := c.Bind(labels...)
 		boundInstrument.Add(ctx, -76)
 		meter.RecordBatch(ctx, labels, c.Measurement(-100.1))
-		checkSyncBatches(ctx, t, labels, mockSDK, otel.Float64NumberKind, otel.UpDownCounterInstrumentKind, c.SyncImpl(),
+		checkSyncBatches(ctx, t, labels, mockSDK, number.Float64Kind, otel.UpDownCounterInstrumentKind, c.SyncImpl(),
 			100.1, -76, -100.1,
 		)
 	})
@@ -273,7 +274,7 @@ func TestValueRecorder(t *testing.T) {
 		boundInstrument := m.Bind(labels...)
 		boundInstrument.Record(ctx, 0)
 		meter.RecordBatch(ctx, labels, m.Measurement(-100.5))
-		checkSyncBatches(ctx, t, labels, mockSDK, otel.Float64NumberKind, otel.ValueRecorderInstrumentKind, m.SyncImpl(),
+		checkSyncBatches(ctx, t, labels, mockSDK, number.Float64Kind, otel.ValueRecorderInstrumentKind, m.SyncImpl(),
 			42, 0, -100.5,
 		)
 	})
@@ -286,7 +287,7 @@ func TestValueRecorder(t *testing.T) {
 		boundInstrument := m.Bind(labels...)
 		boundInstrument.Record(ctx, 80)
 		meter.RecordBatch(ctx, labels, m.Measurement(0))
-		checkSyncBatches(ctx, t, labels, mockSDK, otel.Int64NumberKind, otel.ValueRecorderInstrumentKind, m.SyncImpl(),
+		checkSyncBatches(ctx, t, labels, mockSDK, number.Int64Kind, otel.ValueRecorderInstrumentKind, m.SyncImpl(),
 			173, 80, 0,
 		)
 	})
@@ -300,7 +301,7 @@ func TestObserverInstruments(t *testing.T) {
 			result.Observe(42.1, labels...)
 		})
 		mockSDK.RunAsyncInstruments()
-		checkObserverBatch(t, labels, mockSDK, otel.Float64NumberKind, otel.ValueObserverInstrumentKind, o.AsyncImpl(),
+		checkObserverBatch(t, labels, mockSDK, number.Float64Kind, otel.ValueObserverInstrumentKind, o.AsyncImpl(),
 			42.1,
 		)
 	})
@@ -311,7 +312,7 @@ func TestObserverInstruments(t *testing.T) {
 			result.Observe(-142, labels...)
 		})
 		mockSDK.RunAsyncInstruments()
-		checkObserverBatch(t, labels, mockSDK, otel.Int64NumberKind, otel.ValueObserverInstrumentKind, o.AsyncImpl(),
+		checkObserverBatch(t, labels, mockSDK, number.Int64Kind, otel.ValueObserverInstrumentKind, o.AsyncImpl(),
 			-142,
 		)
 	})
@@ -322,7 +323,7 @@ func TestObserverInstruments(t *testing.T) {
 			result.Observe(42.1, labels...)
 		})
 		mockSDK.RunAsyncInstruments()
-		checkObserverBatch(t, labels, mockSDK, otel.Float64NumberKind, otel.SumObserverInstrumentKind, o.AsyncImpl(),
+		checkObserverBatch(t, labels, mockSDK, number.Float64Kind, otel.SumObserverInstrumentKind, o.AsyncImpl(),
 			42.1,
 		)
 	})
@@ -333,7 +334,7 @@ func TestObserverInstruments(t *testing.T) {
 			result.Observe(-142, labels...)
 		})
 		mockSDK.RunAsyncInstruments()
-		checkObserverBatch(t, labels, mockSDK, otel.Int64NumberKind, otel.SumObserverInstrumentKind, o.AsyncImpl(),
+		checkObserverBatch(t, labels, mockSDK, number.Int64Kind, otel.SumObserverInstrumentKind, o.AsyncImpl(),
 			-142,
 		)
 	})
@@ -344,7 +345,7 @@ func TestObserverInstruments(t *testing.T) {
 			result.Observe(42.1, labels...)
 		})
 		mockSDK.RunAsyncInstruments()
-		checkObserverBatch(t, labels, mockSDK, otel.Float64NumberKind, otel.UpDownSumObserverInstrumentKind, o.AsyncImpl(),
+		checkObserverBatch(t, labels, mockSDK, number.Float64Kind, otel.UpDownSumObserverInstrumentKind, o.AsyncImpl(),
 			42.1,
 		)
 	})
@@ -355,7 +356,7 @@ func TestObserverInstruments(t *testing.T) {
 			result.Observe(-142, labels...)
 		})
 		mockSDK.RunAsyncInstruments()
-		checkObserverBatch(t, labels, mockSDK, otel.Int64NumberKind, otel.UpDownSumObserverInstrumentKind, o.AsyncImpl(),
+		checkObserverBatch(t, labels, mockSDK, number.Int64Kind, otel.UpDownSumObserverInstrumentKind, o.AsyncImpl(),
 			-142,
 		)
 	})
@@ -399,14 +400,14 @@ func TestBatchObserverInstruments(t *testing.T) {
 
 	m1 := got.Measurements[0]
 	require.Equal(t, impl1, m1.Instrument.Implementation().(*oteltest.Async))
-	require.Equal(t, 0, m1.Number.CompareNumber(otel.Int64NumberKind, oteltest.ResolveNumberByKind(t, otel.Int64NumberKind, 42)))
+	require.Equal(t, 0, m1.Number.CompareNumber(number.Int64Kind, oteltest.ResolveNumberByKind(t, number.Int64Kind, 42)))
 
 	m2 := got.Measurements[1]
 	require.Equal(t, impl2, m2.Instrument.Implementation().(*oteltest.Async))
-	require.Equal(t, 0, m2.Number.CompareNumber(otel.Float64NumberKind, oteltest.ResolveNumberByKind(t, otel.Float64NumberKind, 42)))
+	require.Equal(t, 0, m2.Number.CompareNumber(number.Float64Kind, oteltest.ResolveNumberByKind(t, number.Float64Kind, 42)))
 }
 
-func checkObserverBatch(t *testing.T, labels []label.KeyValue, mock *oteltest.MeterImpl, nkind otel.NumberKind, mkind otel.InstrumentKind, observer otel.AsyncImpl, expected float64) {
+func checkObserverBatch(t *testing.T, labels []label.KeyValue, mock *oteltest.MeterImpl, nkind number.Kind, mkind otel.InstrumentKind, observer otel.AsyncImpl, expected float64) {
 	t.Helper()
 	assert.Len(t, mock.MeasurementBatches, 1)
 	if len(mock.MeasurementBatches) < 1 {
diff --git a/oteltest/meter.go b/oteltest/meter.go
index 44abe730..3cf75d8e 100644
--- a/oteltest/meter.go
+++ b/oteltest/meter.go
@@ -23,7 +23,8 @@ import (
 	apimetric "go.opentelemetry.io/otel"
 	internalmetric "go.opentelemetry.io/otel/internal/metric"
 	"go.opentelemetry.io/otel/label"
-	"go.opentelemetry.io/otel/registry"
+	"go.opentelemetry.io/otel/metric/number"
+	"go.opentelemetry.io/otel/metric/registry"
 )
 
 type (
@@ -51,7 +52,7 @@ type (
 
 	Measurement struct {
 		// Number needs to be aligned for 64-bit atomic operations.
-		Number     apimetric.Number
+		Number     number.Number
 		Instrument apimetric.InstrumentImpl
 	}
 
@@ -97,18 +98,18 @@ func (s *Sync) Bind(labels []label.KeyValue) apimetric.BoundSyncImpl {
 	}
 }
 
-func (s *Sync) RecordOne(ctx context.Context, number apimetric.Number, labels []label.KeyValue) {
+func (s *Sync) RecordOne(ctx context.Context, number number.Number, labels []label.KeyValue) {
 	s.meter.doRecordSingle(ctx, labels, s, number)
 }
 
-func (h *Handle) RecordOne(ctx context.Context, number apimetric.Number) {
+func (h *Handle) RecordOne(ctx context.Context, number number.Number) {
 	h.Instrument.meter.doRecordSingle(ctx, h.Labels, h.Instrument, number)
 }
 
 func (h *Handle) Unbind() {
 }
 
-func (m *MeterImpl) doRecordSingle(ctx context.Context, labels []label.KeyValue, instrument apimetric.InstrumentImpl, number apimetric.Number) {
+func (m *MeterImpl) doRecordSingle(ctx context.Context, labels []label.KeyValue, instrument apimetric.InstrumentImpl, number number.Number) {
 	m.collect(ctx, labels, []Measurement{{
 		Instrument: instrument,
 		Number:     number,
@@ -200,7 +201,7 @@ type Measured struct {
 	InstrumentationName    string
 	InstrumentationVersion string
 	Labels                 map[label.Key]label.Value
-	Number                 otel.Number
+	Number                 number.Number
 }
 
 // LabelsToMap converts label set to keyValue map, to be easily used in tests
@@ -230,13 +231,13 @@ func AsStructs(batches []Batch) []Measured {
 }
 
 // ResolveNumberByKind takes defined metric descriptor creates a concrete typed metric number
-func ResolveNumberByKind(t *testing.T, kind otel.NumberKind, value float64) otel.Number {
+func ResolveNumberByKind(t *testing.T, kind number.Kind, value float64) number.Number {
 	t.Helper()
 	switch kind {
-	case otel.Int64NumberKind:
-		return otel.NewInt64Number(int64(value))
-	case otel.Float64NumberKind:
-		return otel.NewFloat64Number(value)
+	case number.Int64Kind:
+		return number.NewInt64Number(int64(value))
+	case number.Float64Kind:
+		return number.NewFloat64Number(value)
 	}
 	panic("invalid number kind")
 }
diff --git a/sdk/export/metric/exportkind_test.go b/sdk/export/metric/exportkind_test.go
index 030aff57..b71b0f4f 100644
--- a/sdk/export/metric/exportkind_test.go
+++ b/sdk/export/metric/exportkind_test.go
@@ -20,6 +20,7 @@ import (
 	"github.com/stretchr/testify/require"
 
 	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/metric/number"
 	"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
 )
 
@@ -58,7 +59,7 @@ func TestExportKindSelectors(t *testing.T) {
 	seks := StatelessExportKindSelector()
 
 	for _, ikind := range append(deltaMemoryKinds, cumulativeMemoryKinds...) {
-		desc := otel.NewDescriptor("instrument", ikind, otel.Int64NumberKind)
+		desc := otel.NewDescriptor("instrument", ikind, number.Int64Kind)
 
 		var akind aggregation.Kind
 		if ikind.Adding() {
diff --git a/sdk/export/metric/metrictest/test.go b/sdk/export/metric/metrictest/test.go
index c9235a40..26523be9 100644
--- a/sdk/export/metric/metrictest/test.go
+++ b/sdk/export/metric/metrictest/test.go
@@ -23,6 +23,7 @@ import (
 
 	"go.opentelemetry.io/otel"
 	"go.opentelemetry.io/otel/label"
+	"go.opentelemetry.io/otel/metric/number"
 	export "go.opentelemetry.io/otel/sdk/export/metric"
 	"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
 	"go.opentelemetry.io/otel/sdk/resource"
@@ -48,7 +49,7 @@ type NoopAggregator struct{}
 var _ export.Aggregator = (*NoopAggregator)(nil)
 
 // Update implements export.Aggregator.
-func (NoopAggregator) Update(context.Context, otel.Number, *otel.Descriptor) error {
+func (NoopAggregator) Update(context.Context, number.Number, *otel.Descriptor) error {
 	return nil
 }
 
diff --git a/sdk/metric/aggregator/aggregator_test.go b/sdk/metric/aggregator/aggregator_test.go
index 0cc94387..59bcb100 100644
--- a/sdk/metric/aggregator/aggregator_test.go
+++ b/sdk/metric/aggregator/aggregator_test.go
@@ -22,6 +22,7 @@ import (
 	"github.com/stretchr/testify/require"
 
 	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/metric/number"
 	"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
 	"go.opentelemetry.io/otel/sdk/metric/aggregator"
 	"go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue"
@@ -40,10 +41,10 @@ func TestInconsistentAggregatorErr(t *testing.T) {
 
 func testRangeNaN(t *testing.T, desc *otel.Descriptor) {
 	// If the descriptor uses int64 numbers, this won't register as NaN
-	nan := otel.NewFloat64Number(math.NaN())
+	nan := number.NewFloat64Number(math.NaN())
 	err := aggregator.RangeTest(nan, desc)
 
-	if desc.NumberKind() == otel.Float64NumberKind {
+	if desc.NumberKind() == number.Float64Kind {
 		require.Equal(t, aggregation.ErrNaNInput, err)
 	} else {
 		require.Nil(t, err)
@@ -51,14 +52,14 @@ func testRangeNaN(t *testing.T, desc *otel.Descriptor) {
 }
 
 func testRangeNegative(t *testing.T, desc *otel.Descriptor) {
-	var neg, pos otel.Number
+	var neg, pos number.Number
 
-	if desc.NumberKind() == otel.Float64NumberKind {
-		pos = otel.NewFloat64Number(+1)
-		neg = otel.NewFloat64Number(-1)
+	if desc.NumberKind() == number.Float64Kind {
+		pos = number.NewFloat64Number(+1)
+		neg = number.NewFloat64Number(-1)
 	} else {
-		pos = otel.NewInt64Number(+1)
-		neg = otel.NewInt64Number(-1)
+		pos = number.NewInt64Number(+1)
+		neg = number.NewInt64Number(-1)
 	}
 
 	posErr := aggregator.RangeTest(pos, desc)
@@ -70,7 +71,7 @@ func testRangeNegative(t *testing.T, desc *otel.Descriptor) {
 
 func TestRangeTest(t *testing.T) {
 	// Only Counters implement a range test.
-	for _, nkind := range []otel.NumberKind{otel.Float64NumberKind, otel.Int64NumberKind} {
+	for _, nkind := range []number.Kind{number.Float64Kind, number.Int64Kind} {
 		t.Run(nkind.String(), func(t *testing.T) {
 			desc := otel.NewDescriptor(
 				"name",
@@ -83,7 +84,7 @@ func TestRangeTest(t *testing.T) {
 }
 
 func TestNaNTest(t *testing.T) {
-	for _, nkind := range []otel.NumberKind{otel.Float64NumberKind, otel.Int64NumberKind} {
+	for _, nkind := range []number.Kind{number.Float64Kind, number.Int64Kind} {
 		t.Run(nkind.String(), func(t *testing.T) {
 			for _, mkind := range []otel.InstrumentKind{
 				otel.CounterInstrumentKind,
diff --git a/sdk/metric/aggregator/aggregatortest/test.go b/sdk/metric/aggregator/aggregatortest/test.go
index b0973147..6eb165bb 100644
--- a/sdk/metric/aggregator/aggregatortest/test.go
+++ b/sdk/metric/aggregator/aggregatortest/test.go
@@ -24,6 +24,7 @@ import (
 
 	"go.opentelemetry.io/otel"
 	ottest "go.opentelemetry.io/otel/internal/testing"
+	"go.opentelemetry.io/otel/metric/number"
 	export "go.opentelemetry.io/otel/sdk/export/metric"
 	"go.opentelemetry.io/otel/sdk/metric/aggregator"
 )
@@ -31,29 +32,29 @@ import (
 const Magnitude = 1000
 
 type Profile struct {
-	NumberKind otel.NumberKind
-	Random     func(sign int) otel.Number
+	NumberKind number.Kind
+	Random     func(sign int) number.Number
 }
 
 func newProfiles() []Profile {
 	rnd := rand.New(rand.NewSource(rand.Int63()))
 	return []Profile{
 		{
-			NumberKind: otel.Int64NumberKind,
-			Random: func(sign int) otel.Number {
-				return otel.NewInt64Number(int64(sign) * int64(rnd.Intn(Magnitude+1)))
+			NumberKind: number.Int64Kind,
+			Random: func(sign int) number.Number {
+				return number.NewInt64Number(int64(sign) * int64(rnd.Intn(Magnitude+1)))
 			},
 		},
 		{
-			NumberKind: otel.Float64NumberKind,
-			Random: func(sign int) otel.Number {
-				return otel.NewFloat64Number(float64(sign) * rnd.Float64() * Magnitude)
+			NumberKind: number.Float64Kind,
+			Random: func(sign int) number.Number {
+				return number.NewFloat64Number(float64(sign) * rnd.Float64() * Magnitude)
 			},
 		},
 	}
 }
 
-func NewAggregatorTest(mkind otel.InstrumentKind, nkind otel.NumberKind) *otel.Descriptor {
+func NewAggregatorTest(mkind otel.InstrumentKind, nkind number.Kind) *otel.Descriptor {
 	desc := otel.NewDescriptor("test.name", mkind, nkind)
 	return &desc
 }
@@ -85,17 +86,17 @@ func TestMain(m *testing.M) {
 
 type Numbers struct {
 	// numbers has to be aligned for 64-bit atomic operations.
-	numbers []otel.Number
-	kind    otel.NumberKind
+	numbers []number.Number
+	kind    number.Kind
 }
 
-func NewNumbers(kind otel.NumberKind) Numbers {
+func NewNumbers(kind number.Kind) Numbers {
 	return Numbers{
 		kind: kind,
 	}
 }
 
-func (n *Numbers) Append(v otel.Number) {
+func (n *Numbers) Append(v number.Number) {
 	n.numbers = append(n.numbers, v)
 }
 
@@ -115,8 +116,8 @@ func (n *Numbers) Swap(i, j int) {
 	n.numbers[i], n.numbers[j] = n.numbers[j], n.numbers[i]
 }
 
-func (n *Numbers) Sum() otel.Number {
-	var sum otel.Number
+func (n *Numbers) Sum() number.Number {
+	var sum number.Number
 	for _, num := range n.numbers {
 		sum.AddNumber(n.kind, num)
 	}
@@ -127,16 +128,16 @@ func (n *Numbers) Count() int64 {
 	return int64(len(n.numbers))
 }
 
-func (n *Numbers) Min() otel.Number {
+func (n *Numbers) Min() number.Number {
 	return n.numbers[0]
 }
 
-func (n *Numbers) Max() otel.Number {
+func (n *Numbers) Max() number.Number {
 	return n.numbers[len(n.numbers)-1]
 }
 
 // Median() is an alias for Quantile(0.5).
-func (n *Numbers) Median() otel.Number {
+func (n *Numbers) Median() number.Number {
 	// Note that len(n.numbers) is 1 greater than the max element
 	// index, so dividing by two rounds up.  This gives the
 	// intended definition for Quantile() in tests, which is to
@@ -145,12 +146,12 @@ func (n *Numbers) Median() otel.Number {
 	return n.numbers[len(n.numbers)/2]
 }
 
-func (n *Numbers) Points() []otel.Number {
+func (n *Numbers) Points() []number.Number {
 	return n.numbers
 }
 
 // Performs the same range test the SDK does on behalf of the aggregator.
-func CheckedUpdate(t *testing.T, agg export.Aggregator, number otel.Number, descriptor *otel.Descriptor) {
+func CheckedUpdate(t *testing.T, agg export.Aggregator, number number.Number, descriptor *otel.Descriptor) {
 	ctx := context.Background()
 
 	// Note: Aggregator tests are written assuming that the SDK
diff --git a/sdk/metric/aggregator/array/array_test.go b/sdk/metric/aggregator/array/array_test.go
index 4ea1134b..a668f1e0 100644
--- a/sdk/metric/aggregator/array/array_test.go
+++ b/sdk/metric/aggregator/array/array_test.go
@@ -23,6 +23,7 @@ import (
 	"github.com/stretchr/testify/require"
 
 	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/metric/number"
 	"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
 	"go.opentelemetry.io/otel/sdk/metric/aggregator/aggregatortest"
 )
@@ -227,10 +228,10 @@ func TestArrayErrors(t *testing.T) {
 
 		descriptor := aggregatortest.NewAggregatorTest(otel.ValueRecorderInstrumentKind, profile.NumberKind)
 
-		aggregatortest.CheckedUpdate(t, agg, otel.Number(0), descriptor)
+		aggregatortest.CheckedUpdate(t, agg, number.Number(0), descriptor)
 
-		if profile.NumberKind == otel.Float64NumberKind {
-			aggregatortest.CheckedUpdate(t, agg, otel.NewFloat64Number(math.NaN()), descriptor)
+		if profile.NumberKind == number.Float64Kind {
+			aggregatortest.CheckedUpdate(t, agg, number.NewFloat64Number(math.NaN()), descriptor)
 		}
 		require.NoError(t, agg.SynchronizedMove(ckpt, descriptor))
 
@@ -240,7 +241,7 @@ func TestArrayErrors(t *testing.T) {
 
 		num, err := ckpt.Quantile(0)
 		require.Nil(t, err)
-		require.Equal(t, num, otel.Number(0))
+		require.Equal(t, num, number.Number(0))
 
 		_, err = ckpt.Quantile(-0.0001)
 		require.Error(t, err)
@@ -253,7 +254,7 @@ func TestArrayErrors(t *testing.T) {
 }
 
 func TestArrayFloat64(t *testing.T) {
-	descriptor := aggregatortest.NewAggregatorTest(otel.ValueRecorderInstrumentKind, otel.Float64NumberKind)
+	descriptor := aggregatortest.NewAggregatorTest(otel.ValueRecorderInstrumentKind, number.Float64Kind)
 
 	fpsf := func(sign int) []float64 {
 		// Check behavior of a bunch of odd floating
@@ -282,18 +283,18 @@ func TestArrayFloat64(t *testing.T) {
 		}
 	}
 
-	all := aggregatortest.NewNumbers(otel.Float64NumberKind)
+	all := aggregatortest.NewNumbers(number.Float64Kind)
 
 	agg, ckpt := new2()
 
 	for _, f := range fpsf(1) {
-		all.Append(otel.NewFloat64Number(f))
-		aggregatortest.CheckedUpdate(t, agg, otel.NewFloat64Number(f), descriptor)
+		all.Append(number.NewFloat64Number(f))
+		aggregatortest.CheckedUpdate(t, agg, number.NewFloat64Number(f), descriptor)
 	}
 
 	for _, f := range fpsf(-1) {
-		all.Append(otel.NewFloat64Number(f))
-		aggregatortest.CheckedUpdate(t, agg, otel.NewFloat64Number(f), descriptor)
+		all.Append(number.NewFloat64Number(f))
+		aggregatortest.CheckedUpdate(t, agg, number.NewFloat64Number(f), descriptor)
 	}
 
 	require.NoError(t, agg.SynchronizedMove(ckpt, descriptor))
diff --git a/sdk/metric/aggregator/histogram/benchmark_test.go b/sdk/metric/aggregator/histogram/benchmark_test.go
index b554fea7..080715a1 100644
--- a/sdk/metric/aggregator/histogram/benchmark_test.go
+++ b/sdk/metric/aggregator/histogram/benchmark_test.go
@@ -20,6 +20,7 @@ import (
 	"testing"
 
 	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/metric/number"
 	"go.opentelemetry.io/otel/sdk/metric/aggregator/aggregatortest"
 	"go.opentelemetry.io/otel/sdk/metric/aggregator/histogram"
 )
@@ -37,7 +38,7 @@ func benchmarkHistogramSearchFloat64(b *testing.B, size int) {
 	for i := range values {
 		values[i] = rand.Float64() * inputRange
 	}
-	desc := aggregatortest.NewAggregatorTest(otel.ValueRecorderInstrumentKind, otel.Float64NumberKind)
+	desc := aggregatortest.NewAggregatorTest(otel.ValueRecorderInstrumentKind, number.Float64Kind)
 	agg := &histogram.New(1, desc, boundaries)[0]
 	ctx := context.Background()
 
@@ -45,7 +46,7 @@ func benchmarkHistogramSearchFloat64(b *testing.B, size int) {
 	b.ResetTimer()
 
 	for i := 0; i < b.N; i++ {
-		_ = agg.Update(ctx, otel.NewFloat64Number(values[i]), desc)
+		_ = agg.Update(ctx, number.NewFloat64Number(values[i]), desc)
 	}
 }
 
@@ -88,7 +89,7 @@ func benchmarkHistogramSearchInt64(b *testing.B, size int) {
 	for i := range values {
 		values[i] = int64(rand.Float64() * inputRange)
 	}
-	desc := aggregatortest.NewAggregatorTest(otel.ValueRecorderInstrumentKind, otel.Int64NumberKind)
+	desc := aggregatortest.NewAggregatorTest(otel.ValueRecorderInstrumentKind, number.Int64Kind)
 	agg := &histogram.New(1, desc, boundaries)[0]
 	ctx := context.Background()
 
@@ -96,7 +97,7 @@ func benchmarkHistogramSearchInt64(b *testing.B, size int) {
 	b.ResetTimer()
 
 	for i := 0; i < b.N; i++ {
-		_ = agg.Update(ctx, otel.NewInt64Number(values[i]), desc)
+		_ = agg.Update(ctx, number.NewInt64Number(values[i]), desc)
 	}
 }
 
diff --git a/sdk/metric/aggregator/histogram/histogram_test.go b/sdk/metric/aggregator/histogram/histogram_test.go
index d5088c37..2c9c9ee3 100644
--- a/sdk/metric/aggregator/histogram/histogram_test.go
+++ b/sdk/metric/aggregator/histogram/histogram_test.go
@@ -23,6 +23,7 @@ import (
 	"github.com/stretchr/testify/require"
 
 	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/metric/number"
 	"go.opentelemetry.io/otel/sdk/metric/aggregator/aggregatortest"
 	"go.opentelemetry.io/otel/sdk/metric/aggregator/histogram"
 )
@@ -72,7 +73,7 @@ func new4(desc *otel.Descriptor) (_, _, _, _ *histogram.Aggregator) {
 
 func checkZero(t *testing.T, agg *histogram.Aggregator, desc *otel.Descriptor) {
 	asum, err := agg.Sum()
-	require.Equal(t, otel.Number(0), asum, "Empty checkpoint sum = 0")
+	require.Equal(t, number.Number(0), asum, "Empty checkpoint sum = 0")
 	require.NoError(t, err)
 
 	count, err := agg.Count()
@@ -231,7 +232,7 @@ func TestHistogramNotSet(t *testing.T) {
 	})
 }
 
-func calcBuckets(points []otel.Number, profile aggregatortest.Profile) []uint64 {
+func calcBuckets(points []number.Number, profile aggregatortest.Profile) []uint64 {
 	sortedBoundaries := make([]float64, len(boundaries))
 
 	copy(sortedBoundaries, boundaries)
diff --git a/sdk/metric/aggregator/lastvalue/lastvalue_test.go b/sdk/metric/aggregator/lastvalue/lastvalue_test.go
index 48e7bc77..49cc8736 100644
--- a/sdk/metric/aggregator/lastvalue/lastvalue_test.go
+++ b/sdk/metric/aggregator/lastvalue/lastvalue_test.go
@@ -26,6 +26,7 @@ import (
 
 	"go.opentelemetry.io/otel"
 	ottest "go.opentelemetry.io/otel/internal/testing"
+	"go.opentelemetry.io/otel/metric/number"
 	export "go.opentelemetry.io/otel/sdk/export/metric"
 	"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
 	"go.opentelemetry.io/otel/sdk/metric/aggregator/aggregatortest"
@@ -64,7 +65,7 @@ func checkZero(t *testing.T, agg *Aggregator) {
 	lv, ts, err := agg.LastValue()
 	require.True(t, errors.Is(err, aggregation.ErrNoData))
 	require.Equal(t, time.Time{}, ts)
-	require.Equal(t, otel.Number(0), lv)
+	require.Equal(t, number.Number(0), lv)
 }
 
 func TestLastValueUpdate(t *testing.T) {
@@ -73,7 +74,7 @@ func TestLastValueUpdate(t *testing.T) {
 
 		record := aggregatortest.NewAggregatorTest(otel.ValueObserverInstrumentKind, profile.NumberKind)
 
-		var last otel.Number
+		var last number.Number
 		for i := 0; i < count; i++ {
 			x := profile.Random(rand.Intn(1)*2 - 1)
 			last = x
@@ -124,7 +125,7 @@ func TestLastValueMerge(t *testing.T) {
 }
 
 func TestLastValueNotSet(t *testing.T) {
-	descriptor := aggregatortest.NewAggregatorTest(otel.ValueObserverInstrumentKind, otel.Int64NumberKind)
+	descriptor := aggregatortest.NewAggregatorTest(otel.ValueObserverInstrumentKind, number.Int64Kind)
 
 	g, ckpt := new2()
 	require.NoError(t, g.SynchronizedMove(ckpt, descriptor))
diff --git a/sdk/metric/aggregator/minmaxsumcount/mmsc_test.go b/sdk/metric/aggregator/minmaxsumcount/mmsc_test.go
index 4adebc73..2ade604c 100644
--- a/sdk/metric/aggregator/minmaxsumcount/mmsc_test.go
+++ b/sdk/metric/aggregator/minmaxsumcount/mmsc_test.go
@@ -23,6 +23,7 @@ import (
 	"github.com/stretchr/testify/require"
 
 	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/metric/number"
 	"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
 	"go.opentelemetry.io/otel/sdk/metric/aggregator/aggregatortest"
 )
@@ -222,7 +223,7 @@ func TestMaxSumCountNotSet(t *testing.T) {
 		require.NoError(t, agg.SynchronizedMove(ckpt, descriptor))
 
 		asum, err := ckpt.Sum()
-		require.Equal(t, otel.Number(0), asum, "Empty checkpoint sum = 0")
+		require.Equal(t, number.Number(0), asum, "Empty checkpoint sum = 0")
 		require.Nil(t, err)
 
 		count, err := ckpt.Count()
@@ -231,6 +232,6 @@ func TestMaxSumCountNotSet(t *testing.T) {
 
 		max, err := ckpt.Max()
 		require.Equal(t, aggregation.ErrNoData, err)
-		require.Equal(t, otel.Number(0), max)
+		require.Equal(t, number.Number(0), max)
 	})
 }
diff --git a/sdk/metric/aggregator/sum/sum_test.go b/sdk/metric/aggregator/sum/sum_test.go
index af31a98b..a98982c7 100644
--- a/sdk/metric/aggregator/sum/sum_test.go
+++ b/sdk/metric/aggregator/sum/sum_test.go
@@ -23,6 +23,7 @@ import (
 
 	"go.opentelemetry.io/otel"
 	ottest "go.opentelemetry.io/otel/internal/testing"
+	"go.opentelemetry.io/otel/metric/number"
 	"go.opentelemetry.io/otel/sdk/metric/aggregator/aggregatortest"
 )
 
@@ -67,7 +68,7 @@ func TestCounterSum(t *testing.T) {
 
 		descriptor := aggregatortest.NewAggregatorTest(otel.CounterInstrumentKind, profile.NumberKind)
 
-		sum := otel.Number(0)
+		sum := number.Number(0)
 		for i := 0; i < count; i++ {
 			x := profile.Random(+1)
 			sum.AddNumber(profile.NumberKind, x)
@@ -91,7 +92,7 @@ func TestValueRecorderSum(t *testing.T) {
 
 		descriptor := aggregatortest.NewAggregatorTest(otel.ValueRecorderInstrumentKind, profile.NumberKind)
 
-		sum := otel.Number(0)
+		sum := number.Number(0)
 
 		for i := 0; i < count; i++ {
 			r1 := profile.Random(+1)
@@ -117,7 +118,7 @@ func TestCounterMerge(t *testing.T) {
 
 		descriptor := aggregatortest.NewAggregatorTest(otel.CounterInstrumentKind, profile.NumberKind)
 
-		sum := otel.Number(0)
+		sum := number.Number(0)
 		for i := 0; i < count; i++ {
 			x := profile.Random(+1)
 			sum.AddNumber(profile.NumberKind, x)
diff --git a/sdk/metric/correct_test.go b/sdk/metric/correct_test.go
index 4f3aea6c..461e3c51 100644
--- a/sdk/metric/correct_test.go
+++ b/sdk/metric/correct_test.go
@@ -26,6 +26,7 @@ import (
 	"go.opentelemetry.io/otel"
 	"go.opentelemetry.io/otel/global"
 	"go.opentelemetry.io/otel/label"
+	"go.opentelemetry.io/otel/metric/number"
 	export "go.opentelemetry.io/otel/sdk/export/metric"
 	"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
 	metricsdk "go.opentelemetry.io/otel/sdk/metric"
@@ -253,7 +254,7 @@ func TestSDKLabelsDeduplication(t *testing.T) {
 	var actual [][]label.KeyValue
 	for _, rec := range processor.accumulations {
 		sum, _ := rec.Aggregator().(aggregation.Sum).Sum()
-		require.Equal(t, sum, otel.NewInt64Number(2))
+		require.Equal(t, sum, number.NewInt64Number(2))
 
 		kvs := rec.Labels().ToSlice()
 		actual = append(actual, kvs)
diff --git a/sdk/metric/histogram_stress_test.go b/sdk/metric/histogram_stress_test.go
index 078688c5..5105b9c7 100644
--- a/sdk/metric/histogram_stress_test.go
+++ b/sdk/metric/histogram_stress_test.go
@@ -23,11 +23,12 @@ import (
 	"github.com/stretchr/testify/require"
 
 	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/metric/number"
 	"go.opentelemetry.io/otel/sdk/metric/aggregator/histogram"
 )
 
 func TestStressInt64Histogram(t *testing.T) {
-	desc := otel.NewDescriptor("some_metric", otel.ValueRecorderInstrumentKind, otel.Int64NumberKind)
+	desc := otel.NewDescriptor("some_metric", otel.ValueRecorderInstrumentKind, number.Int64Kind)
 
 	alloc := histogram.New(2, &desc, []float64{25, 50, 75})
 	h, ckpt := &alloc[0], &alloc[1]
@@ -41,7 +42,7 @@ func TestStressInt64Histogram(t *testing.T) {
 			case <-ctx.Done():
 				return
 			default:
-				_ = h.Update(ctx, otel.NewInt64Number(rnd.Int63()%100), &desc)
+				_ = h.Update(ctx, number.NewInt64Number(rnd.Int63()%100), &desc)
 			}
 		}
 	}()
diff --git a/sdk/metric/minmaxsumcount_stress_test.go b/sdk/metric/minmaxsumcount_stress_test.go
index c5ca9990..f30404e6 100644
--- a/sdk/metric/minmaxsumcount_stress_test.go
+++ b/sdk/metric/minmaxsumcount_stress_test.go
@@ -21,11 +21,12 @@ import (
 	"time"
 
 	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/metric/number"
 	"go.opentelemetry.io/otel/sdk/metric/aggregator/minmaxsumcount"
 )
 
 func TestStressInt64MinMaxSumCount(t *testing.T) {
-	desc := otel.NewDescriptor("some_metric", otel.ValueRecorderInstrumentKind, otel.Int64NumberKind)
+	desc := otel.NewDescriptor("some_metric", otel.ValueRecorderInstrumentKind, number.Int64Kind)
 	alloc := minmaxsumcount.New(2, &desc)
 	mmsc, ckpt := &alloc[0], &alloc[1]
 
@@ -39,7 +40,7 @@ func TestStressInt64MinMaxSumCount(t *testing.T) {
 			case <-ctx.Done():
 				return
 			default:
-				_ = mmsc.Update(ctx, otel.NewInt64Number(v), &desc)
+				_ = mmsc.Update(ctx, number.NewInt64Number(v), &desc)
 			}
 			v++
 		}
diff --git a/sdk/metric/processor/basic/basic_test.go b/sdk/metric/processor/basic/basic_test.go
index 42c94a44..7d93dabb 100644
--- a/sdk/metric/processor/basic/basic_test.go
+++ b/sdk/metric/processor/basic/basic_test.go
@@ -26,6 +26,7 @@ import (
 
 	"go.opentelemetry.io/otel"
 	"go.opentelemetry.io/otel/label"
+	"go.opentelemetry.io/otel/metric/number"
 	export "go.opentelemetry.io/otel/sdk/export/metric"
 	"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
 	"go.opentelemetry.io/otel/sdk/export/metric/metrictest"
@@ -43,7 +44,7 @@ func TestProcessor(t *testing.T) {
 		kind otel.InstrumentKind
 	}
 	type numberCase struct {
-		kind otel.NumberKind
+		kind number.Kind
 	}
 	type aggregatorCase struct {
 		kind aggregation.Kind
@@ -64,8 +65,8 @@ func TestProcessor(t *testing.T) {
 			} {
 				t.Run(ic.kind.String(), func(t *testing.T) {
 					for _, nc := range []numberCase{
-						{kind: otel.Int64NumberKind},
-						{kind: otel.Float64NumberKind},
+						{kind: number.Int64Kind},
+						{kind: number.Float64Kind},
 					} {
 						t.Run(nc.kind.String(), func(t *testing.T) {
 							for _, ac := range []aggregatorCase{
@@ -94,11 +95,11 @@ func TestProcessor(t *testing.T) {
 	}
 }
 
-func asNumber(nkind otel.NumberKind, value int64) otel.Number {
-	if nkind == otel.Int64NumberKind {
-		return otel.NewInt64Number(value)
+func asNumber(nkind number.Kind, value int64) number.Number {
+	if nkind == number.Int64Kind {
+		return number.NewInt64Number(value)
 	}
-	return otel.NewFloat64Number(float64(value))
+	return number.NewFloat64Number(float64(value))
 }
 
 func updateFor(t *testing.T, desc *otel.Descriptor, selector export.AggregatorSelector, res *resource.Resource, value int64, labs ...label.KeyValue) export.Accumulation {
@@ -114,7 +115,7 @@ func testProcessor(
 	t *testing.T,
 	ekind export.ExportKind,
 	mkind otel.InstrumentKind,
-	nkind otel.NumberKind,
+	nkind number.Kind,
 	akind aggregation.Kind,
 ) {
 	// Note: this selector uses the instrument name to dictate
@@ -294,7 +295,7 @@ func TestBasicInconsistent(t *testing.T) {
 	// Test no start
 	b = basic.New(processorTest.AggregatorSelector(), export.StatelessExportKindSelector())
 
-	desc := otel.NewDescriptor("inst", otel.CounterInstrumentKind, otel.Int64NumberKind)
+	desc := otel.NewDescriptor("inst", otel.CounterInstrumentKind, number.Int64Kind)
 	accum := export.NewAccumulation(&desc, label.EmptySet(), resource.Empty(), metrictest.NoopAggregator{})
 	require.Equal(t, basic.ErrInconsistentState, b.Process(accum))
 
@@ -317,7 +318,7 @@ func TestBasicTimestamps(t *testing.T) {
 	b := basic.New(processorTest.AggregatorSelector(), export.StatelessExportKindSelector())
 	afterNew := time.Now()
 
-	desc := otel.NewDescriptor("inst", otel.CounterInstrumentKind, otel.Int64NumberKind)
+	desc := otel.NewDescriptor("inst", otel.CounterInstrumentKind, number.Int64Kind)
 	accum := export.NewAccumulation(&desc, label.EmptySet(), resource.Empty(), metrictest.NoopAggregator{})
 
 	b.StartCollection()
@@ -363,7 +364,7 @@ func TestStatefulNoMemoryCumulative(t *testing.T) {
 	res := resource.NewWithAttributes(label.String("R", "V"))
 	ekindSel := export.CumulativeExportKindSelector()
 
-	desc := otel.NewDescriptor("inst.sum", otel.CounterInstrumentKind, otel.Int64NumberKind)
+	desc := otel.NewDescriptor("inst.sum", otel.CounterInstrumentKind, number.Int64Kind)
 	selector := processorTest.AggregatorSelector()
 
 	processor := basic.New(selector, ekindSel, basic.WithMemory(false))
@@ -397,7 +398,7 @@ func TestStatefulNoMemoryDelta(t *testing.T) {
 	res := resource.NewWithAttributes(label.String("R", "V"))
 	ekindSel := export.DeltaExportKindSelector()
 
-	desc := otel.NewDescriptor("inst.sum", otel.SumObserverInstrumentKind, otel.Int64NumberKind)
+	desc := otel.NewDescriptor("inst.sum", otel.SumObserverInstrumentKind, number.Int64Kind)
 	selector := processorTest.AggregatorSelector()
 
 	processor := basic.New(selector, ekindSel, basic.WithMemory(false))
@@ -434,7 +435,7 @@ func TestMultiObserverSum(t *testing.T) {
 	} {
 
 		res := resource.NewWithAttributes(label.String("R", "V"))
-		desc := otel.NewDescriptor("observe.sum", otel.SumObserverInstrumentKind, otel.Int64NumberKind)
+		desc := otel.NewDescriptor("observe.sum", otel.SumObserverInstrumentKind, number.Int64Kind)
 		selector := processorTest.AggregatorSelector()
 
 		processor := basic.New(selector, ekindSel, basic.WithMemory(false))
diff --git a/sdk/metric/selector/simple/simple_test.go b/sdk/metric/selector/simple/simple_test.go
index e13bbc28..e3c1fc70 100644
--- a/sdk/metric/selector/simple/simple_test.go
+++ b/sdk/metric/selector/simple/simple_test.go
@@ -20,6 +20,7 @@ import (
 	"github.com/stretchr/testify/require"
 
 	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/metric/number"
 	export "go.opentelemetry.io/otel/sdk/export/metric"
 	"go.opentelemetry.io/otel/sdk/metric/aggregator/array"
 	"go.opentelemetry.io/otel/sdk/metric/aggregator/ddsketch"
@@ -31,12 +32,12 @@ import (
 )
 
 var (
-	testCounterDesc           = otel.NewDescriptor("counter", otel.CounterInstrumentKind, otel.Int64NumberKind)
-	testUpDownCounterDesc     = otel.NewDescriptor("updowncounter", otel.UpDownCounterInstrumentKind, otel.Int64NumberKind)
-	testSumObserverDesc       = otel.NewDescriptor("sumobserver", otel.SumObserverInstrumentKind, otel.Int64NumberKind)
-	testUpDownSumObserverDesc = otel.NewDescriptor("updownsumobserver", otel.UpDownSumObserverInstrumentKind, otel.Int64NumberKind)
-	testValueRecorderDesc     = otel.NewDescriptor("valuerecorder", otel.ValueRecorderInstrumentKind, otel.Int64NumberKind)
-	testValueObserverDesc     = otel.NewDescriptor("valueobserver", otel.ValueObserverInstrumentKind, otel.Int64NumberKind)
+	testCounterDesc           = otel.NewDescriptor("counter", otel.CounterInstrumentKind, number.Int64Kind)
+	testUpDownCounterDesc     = otel.NewDescriptor("updowncounter", otel.UpDownCounterInstrumentKind, number.Int64Kind)
+	testSumObserverDesc       = otel.NewDescriptor("sumobserver", otel.SumObserverInstrumentKind, number.Int64Kind)
+	testUpDownSumObserverDesc = otel.NewDescriptor("updownsumobserver", otel.UpDownSumObserverInstrumentKind, number.Int64Kind)
+	testValueRecorderDesc     = otel.NewDescriptor("valuerecorder", otel.ValueRecorderInstrumentKind, number.Int64Kind)
+	testValueObserverDesc     = otel.NewDescriptor("valueobserver", otel.ValueObserverInstrumentKind, number.Int64Kind)
 )
 
 func oneAgg(sel export.AggregatorSelector, desc *otel.Descriptor) export.Aggregator {
diff --git a/sdk/metric/stress_test.go b/sdk/metric/stress_test.go
index c43e6f52..414f87e6 100644
--- a/sdk/metric/stress_test.go
+++ b/sdk/metric/stress_test.go
@@ -33,6 +33,7 @@ import (
 
 	"go.opentelemetry.io/otel"
 	"go.opentelemetry.io/otel/label"
+	"go.opentelemetry.io/otel/metric/number"
 	export "go.opentelemetry.io/otel/sdk/export/metric"
 	"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
 	"go.opentelemetry.io/otel/sdk/metric/processor/processortest"
@@ -73,17 +74,17 @@ type (
 
 	testImpl struct {
 		newInstrument  func(meter otel.Meter, name string) SyncImpler
-		getUpdateValue func() otel.Number
-		operate        func(interface{}, context.Context, otel.Number, []label.KeyValue)
+		getUpdateValue func() number.Number
+		operate        func(interface{}, context.Context, number.Number, []label.KeyValue)
 		newStore       func() interface{}
 
 		// storeCollect and storeExpect are the same for
 		// counters, different for lastValues, to ensure we are
 		// testing the timestamps correctly.
-		storeCollect func(store interface{}, value otel.Number, ts time.Time)
-		storeExpect  func(store interface{}, value otel.Number)
-		readStore    func(store interface{}) otel.Number
-		equalValues  func(a, b otel.Number) bool
+		storeCollect func(store interface{}, value number.Number, ts time.Time)
+		storeExpect  func(store interface{}, value number.Number)
+		readStore    func(store interface{}) number.Number
+		equalValues  func(a, b number.Number) bool
 	}
 
 	SyncImpler interface {
@@ -95,7 +96,7 @@ type (
 	// take the later timestamp.
 	lastValueState struct {
 		// raw has to be aligned for 64-bit atomic operations.
-		raw otel.Number
+		raw number.Number
 		ts  time.Time
 	}
 )
@@ -326,11 +327,11 @@ func stressTest(t *testing.T, impl testImpl) {
 	fixture.assertTest(numCollect)
 }
 
-func int64sEqual(a, b otel.Number) bool {
+func int64sEqual(a, b number.Number) bool {
 	return a.AsInt64() == b.AsInt64()
 }
 
-func float64sEqual(a, b otel.Number) bool {
+func float64sEqual(a, b number.Number) bool {
 	diff := math.Abs(a.AsFloat64() - b.AsFloat64())
 	return diff < math.Abs(a.AsFloat64())*epsilon
 }
@@ -342,30 +343,30 @@ func intCounterTestImpl() testImpl {
 		newInstrument: func(meter otel.Meter, name string) SyncImpler {
 			return Must(meter).NewInt64Counter(name + ".sum")
 		},
-		getUpdateValue: func() otel.Number {
+		getUpdateValue: func() number.Number {
 			for {
 				x := int64(rand.Intn(100))
 				if x != 0 {
-					return otel.NewInt64Number(x)
+					return number.NewInt64Number(x)
 				}
 			}
 		},
-		operate: func(inst interface{}, ctx context.Context, value otel.Number, labels []label.KeyValue) {
+		operate: func(inst interface{}, ctx context.Context, value number.Number, labels []label.KeyValue) {
 			counter := inst.(otel.Int64Counter)
 			counter.Add(ctx, value.AsInt64(), labels...)
 		},
 		newStore: func() interface{} {
-			n := otel.NewInt64Number(0)
+			n := number.NewInt64Number(0)
 			return &n
 		},
-		storeCollect: func(store interface{}, value otel.Number, _ time.Time) {
-			store.(*otel.Number).AddInt64Atomic(value.AsInt64())
+		storeCollect: func(store interface{}, value number.Number, _ time.Time) {
+			store.(*number.Number).AddInt64Atomic(value.AsInt64())
 		},
-		storeExpect: func(store interface{}, value otel.Number) {
-			store.(*otel.Number).AddInt64Atomic(value.AsInt64())
+		storeExpect: func(store interface{}, value number.Number) {
+			store.(*number.Number).AddInt64Atomic(value.AsInt64())
 		},
-		readStore: func(store interface{}) otel.Number {
-			return store.(*otel.Number).AsNumberAtomic()
+		readStore: func(store interface{}) number.Number {
+			return store.(*number.Number).AsNumberAtomic()
 		},
 		equalValues: int64sEqual,
 	}
@@ -380,30 +381,30 @@ func floatCounterTestImpl() testImpl {
 		newInstrument: func(meter otel.Meter, name string) SyncImpler {
 			return Must(meter).NewFloat64Counter(name + ".sum")
 		},
-		getUpdateValue: func() otel.Number {
+		getUpdateValue: func() number.Number {
 			for {
 				x := rand.Float64()
 				if x != 0 {
-					return otel.NewFloat64Number(x)
+					return number.NewFloat64Number(x)
 				}
 			}
 		},
-		operate: func(inst interface{}, ctx context.Context, value otel.Number, labels []label.KeyValue) {
+		operate: func(inst interface{}, ctx context.Context, value number.Number, labels []label.KeyValue) {
 			counter := inst.(otel.Float64Counter)
 			counter.Add(ctx, value.AsFloat64(), labels...)
 		},
 		newStore: func() interface{} {
-			n := otel.NewFloat64Number(0.0)
+			n := number.NewFloat64Number(0.0)
 			return &n
 		},
-		storeCollect: func(store interface{}, value otel.Number, _ time.Time) {
-			store.(*otel.Number).AddFloat64Atomic(value.AsFloat64())
+		storeCollect: func(store interface{}, value number.Number, _ time.Time) {
+			store.(*number.Number).AddFloat64Atomic(value.AsFloat64())
 		},
-		storeExpect: func(store interface{}, value otel.Number) {
-			store.(*otel.Number).AddFloat64Atomic(value.AsFloat64())
+		storeExpect: func(store interface{}, value number.Number) {
+			store.(*number.Number).AddFloat64Atomic(value.AsFloat64())
 		},
-		readStore: func(store interface{}) otel.Number {
-			return store.(*otel.Number).AsNumberAtomic()
+		readStore: func(store interface{}) number.Number {
+			return store.(*number.Number).AsNumberAtomic()
 		},
 		equalValues: float64sEqual,
 	}
@@ -420,20 +421,20 @@ func intLastValueTestImpl() testImpl {
 		newInstrument: func(meter otel.Meter, name string) SyncImpler {
 			return Must(meter).NewInt64ValueRecorder(name + ".lastvalue")
 		},
-		getUpdateValue: func() otel.Number {
+		getUpdateValue: func() number.Number {
 			r1 := rand.Int63()
-			return otel.NewInt64Number(rand.Int63() - r1)
+			return number.NewInt64Number(rand.Int63() - r1)
 		},
-		operate: func(inst interface{}, ctx context.Context, value otel.Number, labels []label.KeyValue) {
+		operate: func(inst interface{}, ctx context.Context, value number.Number, labels []label.KeyValue) {
 			valuerecorder := inst.(otel.Int64ValueRecorder)
 			valuerecorder.Record(ctx, value.AsInt64(), labels...)
 		},
 		newStore: func() interface{} {
 			return &lastValueState{
-				raw: otel.NewInt64Number(0),
+				raw: number.NewInt64Number(0),
 			}
 		},
-		storeCollect: func(store interface{}, value otel.Number, ts time.Time) {
+		storeCollect: func(store interface{}, value number.Number, ts time.Time) {
 			gs := store.(*lastValueState)
 
 			if !ts.Before(gs.ts) {
@@ -441,11 +442,11 @@ func intLastValueTestImpl() testImpl {
 				gs.raw.SetInt64Atomic(value.AsInt64())
 			}
 		},
-		storeExpect: func(store interface{}, value otel.Number) {
+		storeExpect: func(store interface{}, value number.Number) {
 			gs := store.(*lastValueState)
 			gs.raw.SetInt64Atomic(value.AsInt64())
 		},
-		readStore: func(store interface{}) otel.Number {
+		readStore: func(store interface{}) number.Number {
 			gs := store.(*lastValueState)
 			return gs.raw.AsNumberAtomic()
 		},
@@ -462,19 +463,19 @@ func floatLastValueTestImpl() testImpl {
 		newInstrument: func(meter otel.Meter, name string) SyncImpler {
 			return Must(meter).NewFloat64ValueRecorder(name + ".lastvalue")
 		},
-		getUpdateValue: func() otel.Number {
-			return otel.NewFloat64Number((-0.5 + rand.Float64()) * 100000)
+		getUpdateValue: func() number.Number {
+			return number.NewFloat64Number((-0.5 + rand.Float64()) * 100000)
 		},
-		operate: func(inst interface{}, ctx context.Context, value otel.Number, labels []label.KeyValue) {
+		operate: func(inst interface{}, ctx context.Context, value number.Number, labels []label.KeyValue) {
 			valuerecorder := inst.(otel.Float64ValueRecorder)
 			valuerecorder.Record(ctx, value.AsFloat64(), labels...)
 		},
 		newStore: func() interface{} {
 			return &lastValueState{
-				raw: otel.NewFloat64Number(0),
+				raw: number.NewFloat64Number(0),
 			}
 		},
-		storeCollect: func(store interface{}, value otel.Number, ts time.Time) {
+		storeCollect: func(store interface{}, value number.Number, ts time.Time) {
 			gs := store.(*lastValueState)
 
 			if !ts.Before(gs.ts) {
@@ -482,11 +483,11 @@ func floatLastValueTestImpl() testImpl {
 				gs.raw.SetFloat64Atomic(value.AsFloat64())
 			}
 		},
-		storeExpect: func(store interface{}, value otel.Number) {
+		storeExpect: func(store interface{}, value number.Number) {
 			gs := store.(*lastValueState)
 			gs.raw.SetFloat64Atomic(value.AsFloat64())
 		},
-		readStore: func(store interface{}) otel.Number {
+		readStore: func(store interface{}) number.Number {
 			gs := store.(*lastValueState)
 			return gs.raw.AsNumberAtomic()
 		},