zoukankan      html  css  js  c++  java
  • Golang四舍五入保留两位小数

    Sprintf

    四舍六入:

    	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
    

    公众号:李田路口

  • 相关阅读:
    PowerDesigner反向工程操作步骤 以PowerDesigner15为例
    RegularExpressionValidator控件中正则表达式用法
    在C#中进行数据纵向不定行转横向列,多条信息成一行,例如员工薪资信息
    Oracle常见等待事件说明
    ORACLE 绑定变量用法总结(转)
    Configure Oracle 11gR2 RAC 一节点执行root.sh脚本报错
    ORACLE ASH/AWR
    db file sequential read 事件的优化(一)
    Redo Log Buffer的大小设置转载
    Oracle 判断 并 手动收集 统计信息 脚本
  • 原文地址:https://www.cnblogs.com/dubinyang/p/13201108.html
Copyright © 2011-2022 走看看