My problem looks like very simple, but I cat not solve it yet.. User enters a money amount xx.xx as a string. After that I convert string to float value (some dollars, some cents), for example, let it be 655.18 (float64) Then, I need to convert this amount to cents - 655.18*100 and the result is 65517.9999999, so when I cast this value to int, I get 65517, so 1 cent was lost. How can I avoid this behaviour?
Code:
package main
import (
"fmt"
"strconv"
)
func CheckParamsPur(sa string) (amount float64) {
amount, _ = strconv.ParseFloat(sa, 64)
return amount
}
func main() {
fmt.Print("Enter a number: ")
var input string
fmt.Scanf("%s", &input)
amount := int(CheckParamsPur(input) * (100))
fmt.Println(amount)
}
string
to float to integerIf you first want to start with parsing the amount to a float, then in the next step instead of converting, use rounding.
Since conversion keeps the integer part, add 0.5
to it before converting. So if the fraction part was less than 0.5
, adding 0.5
will not increase the integer part and so after conversion the integer part will be the same (rounding down). If fraction part was greater than 0.5, adding 0.5 to it will increase the integer part, and after conversion we get 1 higher of the original integer part (rounding up).
In your case, after multiplying by 100, add 0.5 before doing the conversion :
f := 655.17
i := int(f*100 + 0.5)
fmt.Println(i)
Output (try it on the Go Playground):
65517
Read related question which covers this and more: Golang Round to Nearest 0.05
Another option is to skip floating point numbers entirely. To do that, we can parse the input string
which supposed to hold a floating point number as 2 integers separated by a dot .
: "dollars.cents"
(where dollars
and cents
are both integers):
s := "655.17"
var dollars int64
var cents uint64
if _, err := fmt.Sscanf(s, "%d.%d", &dollars, ¢s); err != nil {
panic(err)
}
if cents > 99 {
panic("cents cannot be greater than 99")
}
var total int64
if dollars >= 0 {
total = dollars*100 + int64(cents)
} else {
total = dollars*100 - int64(cents)
}
fmt.Println(total)
Output again is (try it on the Go Playground):
65517
Note: The above parsing code requires you to enter cents using 2 digits, e.g. 655.70
, entering 655.7
would give bad results.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With