The following code should work for a lot of simple use cases with relatively small numbers and small precision inputs. However, it may not work for some uses cases because of numbers overflowing out of the range of float64 numbers, as well as IEEE-754 rounding errors (other languages have this issue as well).
If you care about using larger numbers or need more precision, the following code may not work for your needs, and you should use a helper library (e.g. https://github.com/shopspring/decimal).
I picked up a one-liner round function from elsewhere, and also made toFixed() which depends on round():
func round(num float64) int {
return int(num + math.Copysign(0.5, num))
}
func toFixed(num float64, precision int) float64 {
output := math.Pow(10, float64(precision))
return float64(round(num * output)) / output
}
Usage:
fmt.Println(toFixed(1.2345678, 0)) // 1
fmt.Println(toFixed(1.2345678, 1)) // 1.2
fmt.Println(toFixed(1.2345678, 2)) // 1.23
fmt.Println(toFixed(1.2345678, 3)) // 1.235 (rounded up)
Answer from David Calhoun on Stack OverflowThe following code should work for a lot of simple use cases with relatively small numbers and small precision inputs. However, it may not work for some uses cases because of numbers overflowing out of the range of float64 numbers, as well as IEEE-754 rounding errors (other languages have this issue as well).
If you care about using larger numbers or need more precision, the following code may not work for your needs, and you should use a helper library (e.g. https://github.com/shopspring/decimal).
I picked up a one-liner round function from elsewhere, and also made toFixed() which depends on round():
func round(num float64) int {
return int(num + math.Copysign(0.5, num))
}
func toFixed(num float64, precision int) float64 {
output := math.Pow(10, float64(precision))
return float64(round(num * output)) / output
}
Usage:
fmt.Println(toFixed(1.2345678, 0)) // 1
fmt.Println(toFixed(1.2345678, 1)) // 1.2
fmt.Println(toFixed(1.2345678, 2)) // 1.23
fmt.Println(toFixed(1.2345678, 3)) // 1.235 (rounded up)
You don't need any extra code ... its as simple as
import (
"fmt"
)
func main() {
k := 10 / 3.0
fmt.Printf("%.2f", k)
}
Test Code
math: add Round
How to round big.Float to two decimal places
https://play.golang.org/p/SDNoJTT2tsS
More on reddit.comgo - Round all decimal points in Golang - Stack Overflow
How to round 2100.825 to 2100.83?
The problem is not with your program, it is that the float64 representation of 2100.825 is not exact. Try:
fmt.Printf("%4.24g",2100.825) More on reddit.com Hello, I'm couple of months into Go, but I'm struggling with a quite basic question. I need to precisely divide decimals and round them to two (or n) decimal places. I know there are external libraries to do calculations with decimals, but I'm looking to solve this with the standard library.
This is where I am so far: https://play.golang.org/p/i54VaI747nM
Hi,
I try to round 2100.825 to 2100.83 but get always 2100.82. Here is the code
package main
import (
"fmt"
"math"
)
func main() {
fmt.Println("Expecting 2100.83, but was:", round100(2100.825))
}
func round100(x float64) float64 {
a := x * 100
_, rem := math.Modf(a)
fmt.Println("frac:", rem)
if rem >= 0.5 {
fmt.Println("ceil")
a = math.Ceil(a)
} else {
fmt.Println("floor")
a = math.Floor(a)
}
return a / 100
}If I modify the number to 1100.825 it is properly rounded to 1100.83.
Where is the flaw? And what is the correct implementation of round100?
The problem is not with your program, it is that the float64 representation of 2100.825 is not exact. Try:
fmt.Printf("%4.24g",2100.825)
Are you trying to work with currency or decimal values?
If so, I'd strongly suggest to stay away from floating point (which rounds) and use a decimal-type struct instead, like https://github.com/shopspring/decimal
You can write:
fmt.Printf("%.2f", 1.22225)
(See http://golang.org/pkg/fmt/.)
If you use the fmt.Printf function there is syntax in the formatting string that lets you print floats to a given level of precision like this. The general syntax is %.[numberofdigits]f.
Examples:
fmt.Printf("%.2f" 1.2222225) // output: 1.22
fmt.Printf("%.2f", 1.356) // output: 1.36
One thing to note is that the round doesn't "carry"
fmt.Printf("%.1f", 1.346)
Will output 1.3, not 1.4. Additionally, negative numbers will behave as expected:
fmt.Printf("%.2f", -1.356) // output: -1.36
In the postgres database, quantities are held in type decimal(15,2).
I wonder how to represent this in struct, float64 maybe?