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