The problem is that you try to parse "x.x\n", e.g: 1.8\n. And this returns an error: strconv.ParseFloat: parsing "1.8\n": invalid syntax. You can do a strings.TrimSpace function or to convert feet[:len(feet)-1] to delete \n character
With strings.TrimSpace() (you need to import strings package):
CopyfeetFloat, _ := strconv.ParseFloat(strings.TrimSpace(feet), 64)
Wtih feet[:len(feet)-1]:
CopyfeetFloat, _ := strconv.ParseFloat(feet[:len(feet)-1], 64)
Output in both cases:
Copy10.8 feet converted to meters give you 3.2918400000000005 meters
Answer from Toni Villena on Stack OverflowThe problem is that you try to parse "x.x\n", e.g: 1.8\n. And this returns an error: strconv.ParseFloat: parsing "1.8\n": invalid syntax. You can do a strings.TrimSpace function or to convert feet[:len(feet)-1] to delete \n character
With strings.TrimSpace() (you need to import strings package):
CopyfeetFloat, _ := strconv.ParseFloat(strings.TrimSpace(feet), 64)
Wtih feet[:len(feet)-1]:
CopyfeetFloat, _ := strconv.ParseFloat(feet[:len(feet)-1], 64)
Output in both cases:
Copy10.8 feet converted to meters give you 3.2918400000000005 meters
just tested this solution and also added one more feature:
Copyfunc lbsToGrams(lbs float64) (grams float64) {
return lbs * conversionWeight
}
Find out more on my github here
strconv.ParseFloat() faster altrernatives
parsing - Golang ParseFloat not accurate in example - Stack Overflow
strconv: no way to ParseFloat / ParseInt from []byte
proposal: strconv: add ParseFloatPrefix
Go uses IEEE-754 binary floating-point numbers. Floating-point numbers are imprecise. Don't use them for financial transactions. Use integers.
For example,
package main
import (
"fmt"
"strconv"
"strings"
)
func parseCents(s string) (int64, error) {
n := strings.SplitN(s, ".", 3)
if len(n) != 2 || len(n[1]) != 2 {
err := fmt.Errorf("format error: %s", s)
return 0, err
}
d, err := strconv.ParseInt(n[0], 10, 56)
if err != nil {
return 0, err
}
c, err := strconv.ParseUint(n[1], 10, 8)
if err != nil {
return 0, err
}
if d < 0 {
c = -c
}
return d*100 + int64(c), nil
}
func main() {
s := "79.35"
fmt.Println(parseCents(s))
s = "149.20"
fmt.Println(parseCents(s))
s = "-149.20"
fmt.Println(parseCents(s))
s = "149.2"
fmt.Println(parseCents(s))
}
Playground: https://play.golang.org/p/mGuO51QWyIv
Output:
7935 <nil>
14920 <nil>
-14920 <nil>
0 format error: 149.2
Based on @peterSO's answer, with some bugfix and enhancement:
https://play.golang.org/p/YcRLeEJ7lTA
package main
import (
"fmt"
"strconv"
"strings"
)
func parseCents(s string) (int64, error) {
var ds string
var cs string
n := strings.SplitN(s, ".", 3)
switch len(n) {
case 1:
ds = n[0]
cs = "0"
case 2:
ds = n[0]
switch len(n[1]) {
case 1:
cs = n[1] + "0"
case 2:
cs = n[1]
default:
return 0, fmt.Errorf("invalid format:%s", s)
}
default:
return 0, fmt.Errorf("invalid format:%s", s)
}
d, err := strconv.ParseInt(ds, 10, 0)
if err != nil {
return 0, err
}
c, err := strconv.ParseUint(cs, 10, 0)
if err != nil {
return 0, err
}
cents := d * 100
if strings.HasPrefix(s, "-") {
cents -= int64(c)
} else {
cents += int64(c)
}
return cents, nil
}
func main() {
examples := map[string]int64{
"79.35": 7935,
"149.20": 14920,
"-149.20": -14920,
"149.2": 14920,
"-0.12": -12,
"12": 1200,
"1.234": 0,
"1.2.34": 0,
}
for s, v := range examples {
cents, err := parseCents(s)
fmt.Println(cents, cents == v, err)
}
}