access两位小数不进位_Golang四舍五入保留两位小数

Sprintf

第三位为4则舍去,第三位为6则进位,四舍六入:

  value, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", 9.824), 64)  fmt.Println(value) //9.82  value, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", 9.826), 64)  fmt.Println(value) //9.83

第三位为5且5后有有效数字,满足五入:

  value, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", 9.8251), 64)  fmt.Println(value) //9.83  value, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", 9.8351), 64)  fmt.Println(value) //9.84

第三位为5且5后没有有效数字,第二位为奇数则进位,第二位为偶数则舍去:

  value, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", 9.825), 64)  fmt.Println(value) //9.82  value, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", 9.835), 64)  fmt.Println(value) //9.84

但以上规则并不总是成立:

  value, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", 9.815), 64)  fmt.Println(value) //9.81 居然舍去了  value, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", 9.845), 64)  fmt.Println(value) //9.85 居然进位了

所以,如果想满足正常的四舍五入逻辑,最好不要使用Sprintf处理。

math.Trunc

下面是网上出现较多的另一种写法,结果显示符合四舍五入,但是偶尔会出现精度问题:

  fmt.Println(math.Trunc(9.815*1e2+0.5)*1e-2) //9.82  fmt.Println(math.Trunc(9.825*1e2+0.5)*1e-2) //9.83  fmt.Println(math.Trunc(9.835*1e2+0.5)*1e-2) //9.84  fmt.Println(math.Trunc(9.845*1e2+0.5)*1e-2) //9.85
  fmt.Println(math.Trunc(3.3*1e2+0.5)*1e-2) //3.3000000000000003  fmt.Println(math.Trunc(3.3000000000000003*1e2+0.5) * 1e-2) //3.3000000000000003

同样使用Trunc,稍作调整:

  n10 := math.Pow10(2)  fmt.Println(math.Trunc((9.815+0.5/n10)*n10) / n10) //9.82  fmt.Println(math.Trunc((9.825+0.5/n10)*n10) / n10) //9.83  fmt.Println(math.Trunc((9.835+0.5/n10)*n10) / n10) //9.84  fmt.Println(math.Trunc((9.845+0.5/n10)*n10) / n10) //9.85  fmt.Println(math.Trunc((3.3+0.5/n10)*n10) / n10) //3.3  fmt.Println(math.Trunc((3.3000000000000003+0.5/n10)*n10) / n10) //3.3

符合四舍五入规则。

如果要固定显示两位小数,需转换为string类型,前提是传入的数值,已经做过两位小数处理,否则依旧会有进位问题:

  value := strconv.FormatFloat(3, 'f', 2, 64)  fmt.Println(value) //3.00    value = strconv.FormatFloat(3.3, 'f', 2, 64)  fmt.Println(value) //3.30    value = strconv.FormatFloat(9.815, 'f', 2, 64)  fmt.Println(value) //9.81 被舍去    value = strconv.FormatFloat(9.82, 'f', 2, 64)  fmt.Println(value) //9.82

内容修改

错误示例:

n10 := math.Pow10(2)fmt.Println(math.Trunc((129.975+0.5/n10)*n10) / n10) // 129.97fmt.Println(math.Trunc((34423.125+0.5/n10)*n10) / n10) // 34423.12

代码修改:

package mainimport (  "fmt"  "github.com/shopspring/decimal")func main() {  v1, _ := decimal.NewFromFloat(9.824).Round(2).Float64()  v2, _ := decimal.NewFromFloat(9.826).Round(2).Float64()  v3, _ := decimal.NewFromFloat(9.8251).Round(2).Float64()  fmt.Println(v1, v2, v3)  v4, _ := decimal.NewFromFloat(9.815).Round(2).Float64()  v5, _ := decimal.NewFromFloat(9.825).Round(2).Float64()  v6, _ := decimal.NewFromFloat(9.835).Round(2).Float64()  v7, _ := decimal.NewFromFloat(9.845).Round(2).Float64()  fmt.Println(v4, v5, v6, v7)  v8, _ := decimal.NewFromFloat(3.3).Round(2).Float64()  v9, _ := decimal.NewFromFloat(3.3000000000000003).Round(2).Float64()  v10, _ := decimal.NewFromFloat(3).Round(2).Float64()  fmt.Println(v8, v9, v10)  v11, _ := decimal.NewFromFloat(129.975).Round(2).Float64()  v12, _ := decimal.NewFromFloat(34423.125).Round(2).Float64()  fmt.Println(v11, v12)}

结果如下:

9.82 9.83 9.839.82 9.83 9.84 9.853.3 3.3 3129.98 34423.13

daec89c7696acca17f6a9b9bfedb8eaf.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值