Reputation: 67
I have an endpoint implemented in golang that can receive amounts with different precision length, ie:
"123"
"123.12"
"123.123123"
I'm using big.Rat internally to deal with these numbers as follows:
import (
"encoding/json"
"math/big"
)
type MyStruct struct {
Amount big.Rat `json:"amount"`
}
func (mystr *MyStruct) MarshalJSON() ([]byte, error) {
type Alias MyStruct
return json.Marshal(&struct {
Amount json.Number `json:"amount"`
*Alias
}{
Amount: json.Number(mystr.Amount.FloatString(2)),
Alias: (*Alias)(mystr),
})
}
func (mystr *MyStruct) UnmarshalJSON(data []byte) error {
type Alias MyStruct
aux := &struct {
Amount json.Number `json:"amount"`
*Alias
}{
Alias: (*Alias)(mystr),
}
if err := json.Unmarshal(data, &aux); err != nil {
return err
}
mystr.Amount = mystr.toRat(aux.Amount.String())
return nil
}
func (mystr *MyStruct) toRat(val string) big.Rat {
ratAmount := new(big.Rat)
ratAmount.SetString(val)
return *ratAmount
}
My problem & question is related to the Marshal method, in particular with this line:
Amount: json.Number(mystr.Amount.FloatString(2)),
Because if the amount in the json has a number with more than two decimal places a rounding takes place and I don't want that, I just want to mantain exactly the same number that was received when I did the Unmarshal method.
This is an example of rounding: https://play.golang.org/p/U6oi_aGc8lE
Is there a way to convert from big.Rat to string without defining the precision?
Thank you very much in advance!
Upvotes: 2
Views: 3128
Reputation: 1745
This should be help:
package main
import (
"fmt"
"math/big"
"strconv"
)
func main() {
n := new(big.Rat)
n.SetString("34.999999")
x,_ := n.Float64()
fmt.Println("Result: "+strconv.FormatFloat(x, 'f', -1, 64))
}
Upvotes: 1