I have a list of structs which should be sorted by the fee value of the structs. I couldn’t use big.Int and big.Float because sort.Slice won’t work with these types. Therefore I created the compareAmount variable which is the converted float version of fee and use that for the sorting. The problem is that an integer overflow happens (I assume), therefore I get wrong results. The below attached code produces the following output:
-2530185498501831 -2.530185498501831e+18
-1018378616691543 -1.018378616691543e+18
-867409028382366 -8.67409028382366e+17
-288718783870437 -2.88718783870437e+17
-190626693543325 -1.90626693543325e+17
-15553651457149158 2.8930926165603937e+18
The objects should be listed from high to low, so I believe the correct result would be if -190626693543325 would be the first element, than -288718783870437 the second as these are closest to 0. But something happens when I convert the numbers and the list is not sorted as I wanted. So my question is that how could I sort my slice of structs based on the big.Int values and produce this output:
-190626693543325 -1.90626693543325e+17
-288718783870437 -2.88718783870437e+17
-867409028382366 -8.67409028382366e+17
-1018378616691543 -1.018378616691543e+18
-2530185498501831 -2.530185498501831e+18
-15553651457149158 2.8930926165603937e+18
package main
import (
"fmt"
"math/big"
"sort"
)
func divBigInt(num *big.Int) *big.Int {
divider := big.NewInt(1000)
divided := big.NewInt(0).Mul(num, divider)
return divided
}
type compareStruct struct {
fee *big.Int
compareAmount float64
}
func main() {
fee1 := big.NewInt(-288718783870437)
fee2 := big.NewInt(-867409028382366)
fee3 := big.NewInt(-190626693543325)
fee4 := big.NewInt(-1018378616691543)
fee5 := big.NewInt(-15553651457149158)
fee6 := big.NewInt(-2530185498501831)
fees := make([]*big.Int, 0)
fees = append(fees, fee1)
fees = append(fees, fee2)
fees = append(fees, fee3)
fees = append(fees, fee4)
fees = append(fees, fee5)
fees = append(fees, fee6)
feeList := make([]compareStruct, 0)
for _, f := range fees {
i1 := compareStruct{fee: f, compareAmount: float64(divBigInt(f).Int64())}
feeList = append(feeList, i1)
}
sort.Slice(feeList, func(i, j int) bool {
return feeList[i].compareAmount < feeList[j].compareAmount
})
for _, x := range feeList {
fmt.Println(x.fee, x.compareAmount)
}
}
>Solution :
big.Int has an Int.Cmp() method, so you can compare them, so you can directly sort big.Int values without any conversion. To sort them descendant to get your desired output:
sort.Slice(feeList, func(i, j int) bool {
return feeList[i].fee.Cmp(feeList[j].fee) > 0
})
Try it on the Go Playground.
Also, if you just want to sort the numbers, the slice of wrapper struct is also needless, you can sort a slice of *big.Int similarly.