package main
import (
\"fmt\"
\"strconv\"
)
func main() {
k := 10/3.0
i := fmt.Sprintf(\"%.2f\", k)
f,_ := strconv.ParseFloat(i, 2)
fmt.Pri
modify from @creack
package main
import (
"fmt"
)
func main() {
//untruncated := 10/3.0
untruncated := 4.565
tmp := int(untruncated*100)
last := int(untruncated*1000)-tmp*10
if last>=5{
tmp += 1
}
truncated := float64(tmp)/100
fmt.Println(untruncated, truncated)
}
I really don't see the point, but you could do something like this without strconv:
package main
import (
"fmt"
)
func main() {
untruncated := 10 / 3.0
truncated := float64(int(untruncated * 100)) / 100
fmt.Println(untruncated, truncated)
}
func FloatPrecision(num float64, precision int) float64 {
p := math.Pow10(precision)
value := float64(int(num*p)) / p
return value
}
The simplest solution is numeric truncation (assuming i
is a float and you want a precision of 2 decimal points):
float64(int(i * 100)) / 100
For example:
i := 123456.789
x := float64(int(i * 100)) / 100
// x = 123456.78
If you're dealing with large numbers (numbers that can cross the max value boundaries), you should know that the above can lead to serious floating point accuracy issues:
i := float64(1<<63) // 9223372036854775808.0
fmt.Println(i, float64(int64(i * 10)) / 10)
Prints: 9.223372036854776e+18 -9.223372036854776e+17
See also:
The answer by threeve brought me to this issue on GitHub where a solution based on math/big
for rounding values is presented - this way the rounding method is used correctly:
package main
import (
"fmt"
"math/big"
)
func main() {
f := new(big.Float).SetMode(big.ToNearestEven).SetFloat64(10/3.0)
// Round to 2 digits using formatting.
f.SetPrec(8)
fmt.Printf("%.2f\n", f)
}
The rounding mode is also respected in threeve's example:
j := 0.045
f := new(big.Float).SetMode(big.AwayFromZero).SetFloat64(j)
// Round to 2 digits using formatting.
f.SetPrec(8)
fmt.Printf("%.2f\n", f)
->
correctly yields 0.05
Also, Go 1.10 has been released and added a math.Round() function, see this excellent answer by icza: Golang Round to Nearest 0.05
package main
import (
"fmt"
"math"
)
func main() {
fmt.Println(Round(10/3.0, 0.01))
}
func Round(x, unit float64) float64 {
return math.Round(x/unit) * unit
}
However, one should not use float
for storing monetary values. (See: Why not use Double or Float to represent currency?)
One way around this is using a library that implements decimal
like https://github.com/ericlagergren/decimal or https://github.com/shopspring/decimal
No one has mentioned using math/big
. The results as pertains to the original question are the same as the accepted answer, but if you are working with floats that require a degree of precision ($money$), then you should use big.Float
.
Per the original question:
package main
import (
"math/big"
"fmt"
)
func main() {
// original question
k := 10 / 3.0
fmt.Println(big.NewFloat(k).Text('f', 2))
}
Unfortunately, you can see that .Text
does not use the defined rounding mode (otherwise this answer might be more useful), but rather always seems to round toward zero:
j := 0.045
fmt.Println(big.NewFloat(j).SetMode(big.AwayFromZero).Text('f', 2)
// out -> 0.04
Nevertheless, there are certain advantages to having your float stored as a big.Float
.