@@ -109,6 +109,53 @@ func (f FixedPoint[T]) Equals(other FixedPoint[T]) bool {
109109 return f .Coefficient .Equals (other .Coefficient ) && f .Scale == other .Scale
110110}
111111
112+ // WithinTolerance returns true if the two FixedPoint values are within the
113+ // given tolerance (in parts per million (PPM)).
114+ func (f FixedPoint [T ]) WithinTolerance (
115+ other FixedPoint [T ], tolerancePpm T ) bool {
116+
117+ // Determine the larger scale between the two fixed-point numbers.
118+ // Both values will be scaled to this larger scale to ensure a
119+ // consistent comparison.
120+ var largerScale uint8
121+ if f .Scale > other .Scale {
122+ largerScale = f .Scale
123+ } else {
124+ largerScale = other .Scale
125+ }
126+
127+ subjectFp := f .ScaleTo (largerScale )
128+ otherFp := other .ScaleTo (largerScale )
129+
130+ var (
131+ // delta will be the absolute difference between the two
132+ // coefficients.
133+ delta T
134+
135+ // maxCoefficient is the larger of the two coefficients.
136+ maxCoefficient T
137+ )
138+ if subjectFp .Coefficient .Gt (otherFp .Coefficient ) {
139+ delta = subjectFp .Coefficient .Sub (otherFp .Coefficient )
140+ maxCoefficient = subjectFp .Coefficient
141+ } else {
142+ delta = otherFp .Coefficient .Sub (subjectFp .Coefficient )
143+ maxCoefficient = otherFp .Coefficient
144+ }
145+
146+ // Calculate the tolerance in absolute terms based on the largest
147+ // coefficient.
148+ //
149+ // tolerancePpm is parts per million, therefore we multiply the delta by
150+ // 1,000,000 instead of dividing the tolerance.
151+ scaledDelta := delta .Mul (NewInt [T ]().FromUint64 (1_000_000 ))
152+
153+ // Compare the scaled delta to the product of the maximum coefficient
154+ // and the tolerance.
155+ toleranceCoefficient := maxCoefficient .Mul (tolerancePpm )
156+ return toleranceCoefficient .Gte (scaledDelta )
157+ }
158+
112159// FixedPointFromUint64 creates a new FixedPoint from the given integer and
113160// scale. Note that the input here should be *unscaled*.
114161func FixedPointFromUint64 [N Int [N ]](value uint64 , scale uint8 ) FixedPoint [N ] {
0 commit comments