@@ -179,3 +179,62 @@ internal fun multiplyAndAdd(d: Long, n: Long, r: Long): Long {
179
179
}
180
180
return safeAdd(safeMultiply(md, n), mr)
181
181
}
182
+
183
+ internal val POWERS_OF_TEN = intArrayOf(
184
+ 1 ,
185
+ 10 ,
186
+ 100 ,
187
+ 1000 ,
188
+ 10000 ,
189
+ 100000 ,
190
+ 1000000 ,
191
+ 10000000 ,
192
+ 100000000 ,
193
+ 1000000000
194
+ )
195
+
196
+ /* *
197
+ * The fraction [fractionalPart]/10^[digits].
198
+ */
199
+ internal class DecimalFraction (
200
+ /* *
201
+ * The numerator of the fraction.
202
+ */
203
+ val fractionalPart : Int ,
204
+ /* *
205
+ * The number of digits after the decimal point.
206
+ */
207
+ val digits : Int
208
+ ): Comparable<DecimalFraction> {
209
+ init {
210
+ require(digits >= 0 ) { " Digits must be non-negative, but was $digits " }
211
+ }
212
+
213
+ /* *
214
+ * The integral numerator of the fraction, but with [newDigits] digits after the decimal point.
215
+ * The rounding is done using the towards-zero rounding mode.
216
+ */
217
+ fun fractionalPartWithNDigits (newDigits : Int ): Int = when {
218
+ newDigits == digits -> fractionalPart
219
+ newDigits > digits -> fractionalPart * POWERS_OF_TEN [newDigits - digits]
220
+ else -> fractionalPart / POWERS_OF_TEN [digits - newDigits]
221
+ }
222
+
223
+ override fun compareTo (other : DecimalFraction ): Int =
224
+ maxOf(digits, other.digits).let { maxPrecision ->
225
+ fractionalPartWithNDigits(maxPrecision).compareTo(other.fractionalPartWithNDigits(maxPrecision))
226
+ }
227
+
228
+ override fun equals (other : Any? ): Boolean = other is DecimalFraction && compareTo(other) == 0
229
+
230
+ override fun toString (): String = buildString {
231
+ val denominator = POWERS_OF_TEN [digits]
232
+ append(fractionalPart / denominator)
233
+ append(' .' )
234
+ append((denominator + (fractionalPart % denominator)).toString().removePrefix(" 1" ))
235
+ }
236
+
237
+ override fun hashCode (): Int {
238
+ throw UnsupportedOperationException (" DecimalFraction is not supposed to be used as a hash key" )
239
+ }
240
+ }
0 commit comments