Go语言的浮点型比较大小、与字符串互转、精准舍入

我们在编程中经常需要对两个浮点型比较大小,下面我就来分享一段这样的代码,同时也展示了Go语言函数式编程的独特魅力:

import (
	"fmt"
	"math"
)

func main() {
	// 设置精确度为0.00001
	var a Accuracy = func() float64 { return 0.00001 }
	fmt.Println(a.Equal(0.11111222, 0.11111222233333)) //打印结果为:true
}

type Accuracy func() float64

func (this Accuracy) Equal(a, b float64) bool {
	return math.Abs(a-b) < this()
}

func (this Accuracy) Greater(a, b float64) bool {
	return math.Max(a, b) == a && math.Abs(a-b) > this()
}

func (this Accuracy) Smaller(a, b float64) bool {
	return math.Max(a, b) == b && math.Abs(a-b) > this()
}

func (this Accuracy) GreaterOrEqual(a, b float64) bool {
	return math.Max(a, b) == a || math.Abs(a-b) < this()
}

func (this Accuracy) SmallerOrEqual(a, b float64) bool {
	return math.Max(a, b) == b || math.Abs(a-b) < this()
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

再来分享一个较完整的处理浮点数的结构体——Floater

import (
	"fmt"
	"math"
	"strconv"
	"strings"
)

type Floater struct {
	numOfDecimalPlaces int
	accuracy           float64
	format             string
}

func NewFloater(numOfDecimalPlaces int) *Floater {
	if numOfDecimalPlaces < 0 || numOfDecimalPlaces > 14 {
		panic("the range of Floater.numOfDecimalPlaces must be between 0 and 14.")
	}
	var accuracy float64 = 1
	if numOfDecimalPlaces > 0 {
		accuracyString := "0." + strings.Repeat("0", numOfDecimalPlaces-1) + "1"
		accuracy, _ = strconv.ParseFloat(accuracyString, 64)
	}
	return &Floater{
		numOfDecimalPlaces: numOfDecimalPlaces,
		accuracy:           accuracy,
		format:             "%0." + strconv.Itoa(numOfDecimalPlaces) + "f",
	}
}

func (this *Floater) NumOfDecimalPlaces() int {
	return this.numOfDecimalPlaces
}

func (this *Floater) Accuracy() float64 {
	return this.accuracy
}

func (this *Floater) Format() string {
	return this.format
}

func (this *Floater) Ftoa(f float64) string {
	return fmt.Sprintf(this.format, f)
}

func (this *Floater) Atof(s string, bitSize int) (float64, error) {
	f, err := strconv.ParseFloat(s, bitSize)
	if err != nil {
		return f, err
	}
	return strconv.ParseFloat(fmt.Sprintf(this.format, f), bitSize)
}

func (this *Floater) Ftof(f float64) float64 {
	f, _ = strconv.ParseFloat(fmt.Sprintf(this.format, f), 64)
	return f
}

func (this *Floater) Atoa(s string, bitSize int) (string, error) {
	f, err := strconv.ParseFloat(s, bitSize)
	if err != nil {
		return s, err
	}
	return fmt.Sprintf(this.format, f), nil
}

func (this *Floater) Equal(a, b float64) bool {
	return math.Abs(a-b) < this.accuracy
}

func (this *Floater) Greater(a, b float64) bool {
	return math.Max(a, b) == a && math.Abs(a-b) > this.accuracy
}

func (this *Floater) Smaller(a, b float64) bool {
	return math.Max(a, b) == b && math.Abs(a-b) > this.accuracy
}

func (this *Floater) GreaterOrEqual(a, b float64) bool {
	return math.Max(a, b) == a || math.Abs(a-b) < this.accuracy
}

func (this *Floater) SmallerOrEqual(a, b float64) bool {
	return math.Max(a, b) == b || math.Abs(a-b) < this.accuracy
}

 

转载于:https://my.oschina.net/henrylee2cn/blog/742764

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值