package main

import (
	"fmt"
	"math"
	"reflect"
	"strconv"
)

func main() {
	a:=0.000
	if(a==0){
		fmt.Println("=0")
	}
	return
	numF:=1.56984
	fmt.Println(Round(numF,9))
	return
	//fmt.Printf("%.2f", 12.0)

	fmt.Print(strconv.ParseFloat(fmt.Sprintf("%.2f", 12.0), 64))
	// 保留两位小数, 通用
	fmt.Println(fmt.Sprintf("%.2f", numF))
	value, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", numF), 64)
	fmt.Println(reflect.TypeOf(value), value)

	num, _ := FormatFloat(numF, 2)
	fmt.Println(reflect.TypeOf(num), num)

	// 舍弃的尾数不为0,强制进位
	num, _ = FormatFloatCeil(0.2205, 2)
	fmt.Println(reflect.TypeOf(num), num)

	// 强制舍弃尾数
	num, _ = FormatFloatFloor(0.2295, 2)
	fmt.Println(reflect.TypeOf(num), num)

	// 四舍六入五考虑,五后非零就进一,五后为零看奇偶,五前为偶应舍去,五前为奇要进一
	fmt.Printf("9.8249    =>    %0.2f(四舍)\n", 9.8249)
	fmt.Printf("9.82671    =>    %0.2f(六入)\n", 9.82671)
	fmt.Printf("9.8351    =>    %0.2f(五后非零就进一)\n", 9.8351)
	fmt.Printf("9.82501    =>    %0.2f(五后非零就进一)\n", 9.82501)
	fmt.Printf("9.8250    =>    %0.2f(五后为零看奇偶,五前为偶应舍去)\n", 9.8250)
	fmt.Printf("9.8350    =>    %0.2f(五后为零看奇偶,五前为奇要进一)\n", 9.8350)
}

// 保留两位小数,舍弃尾数,无进位运算
// 主要逻辑就是先乘,trunc之后再除回去,就达到了保留N位小数的效果
func FormatFloat(num float64, decimal int) (float64, error) {
	// 默认乘1
	d := float64(1)
	if decimal > 0 {
		// 10的N次方
		d = math.Pow10(decimal)
	}
	// math.trunc作用就是返回浮点数的整数部分
	// 再除回去,小数点后无效的0也就不存在了
	res := strconv.FormatFloat(math.Trunc(num*d)/d, 'f', -1, 64)
	return strconv.ParseFloat(res, 64)
}

// 舍弃的尾数不为0,强制进位
func FormatFloatCeil(num float64, decimal int) (float64, error) {
	// 默认乘1
	d := float64(1)
	if decimal > 0 {
		// 10的N次方
		d = math.Pow10(decimal)
	}
	// math.trunc作用就是返回浮点数的整数部分
	// 再除回去,小数点后无效的0也就不存在了
	res := strconv.FormatFloat(math.Ceil(num*d)/d, 'f', -1, 64)
	return strconv.ParseFloat(res, 64)
}

// 强制舍弃尾数
func FormatFloatFloor(num float64, decimal int) (float64, error) {
	// 默认乘1
	d := float64(1)
	if decimal > 0 {
		// 10的N次方
		d = math.Pow10(decimal)
	}
	// math.trunc作用就是返回浮点数的整数部分
	// 再除回去,小数点后无效的0也就不存在了
	res := strconv.FormatFloat(math.Floor(num*d)/d, 'f', -1, 64)
	return strconv.ParseFloat(res, 64)
}


/*
 四舍五入取多少位
@param float64 x 目标分析字符串
@param int wei   取小数多少位
*/
func MyRound(x float64, wei int) float64 {
	if wei == 0 {
		return math.Floor(x + 0.5)
	}
	weis := map[int]float64{
		1: 10,
		2: 100,
		3: 1000,
		4: 10000,
		5: 100000,
		6: 1000000,
	}
	weishu := weis[wei]
	s:=math.Floor(x*weishu+0.5)
	fmt.Println(s)
	return  s/weishu

}

func Round(val float64, precision int) (valueFloat64 float64) {
	//strconv.ParseFloat(fmt.Sprintf("%.2f", 12.0), 64) //两位
	format:="%."+strconv.Itoa(precision)+"f"
	valueFloat64,err:= strconv.ParseFloat(fmt.Sprintf(format, val), 64)
	if(err!=nil){
		panic("round err"+err.Error())
	}
	return
}