Skip to content

Instantly share code, notes, and snippets.

@wfxr
Created September 6, 2018 11:51
Show Gist options
  • Save wfxr/ec6c5cb8615f9862991abe1e92c0f2a3 to your computer and use it in GitHub Desktop.
Save wfxr/ec6c5cb8615f9862991abe1e92c0f2a3 to your computer and use it in GitHub Desktop.
Algorithms
// 保证总和为100%的前提下损失精度最小的百分比Rounding算法
import com.google.common.math.IntMath
fun percentageRound(a: List<Double>, precision: Int): List<Double> {
val factor = IntMath.pow(10, precision)
val scaled = a.map { it * factor }
val rounded = scaled.mapIndexed { i, num -> i to Math.round(num) }
val sum = rounded.fold(0L) { acc, pair -> acc + pair.second }
var diff = sum - factor
return if (diff != 0L) {
val fragment = diff / Math.abs(diff)
rounded.zip(scaled).sortedBy { (a, b) ->
(b - a.second) * fragment
}.map { (a, _) ->
if (diff != 0L) {
diff -= fragment
a.first to a.second - fragment
} else a.first to a.second
}
} else {
rounded
}
.sortedBy { it.first }
.map { it.second / factor.toDouble() }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment