为了账号安全,请及时绑定邮箱和手机立即绑定

Go:使用乘法器将 float64 转换为 int

Go:使用乘法器将 float64 转换为 int

Go
慕莱坞森 2021-11-15 17:14:21
我想转换一个float64数字,让我们也说1.003要1003(整型)。我的实现只是将float64with相乘1000并将其转换为int.package mainimport "fmt"func main() {  var f float64 = 1.003  fmt.Println(int(f * 1000))}但是当我运行该代码时,我得到的1002不是1003. 因为 Go 自动将1.003as存储1.002999...在变量中。在 Golang 上做这种操作的正确方法是什么?
查看完整描述

3 回答

?
慕码人2483693

TA贡献1860条经验 获得超9个赞

Go规范:转换:


数字类型之间的转换


将浮点数转换为整数时,分数将被丢弃(向零截断)。


所以基本上当你将浮点数转换为整数时,只保留整数部分。


如果您只是想避免因用有限位表示而产生的错误,只需0.5在将其转换为int. 不需要外部库或函数调用(来自标准库)。


由于float -> int转换不是四舍五入而是保留整数部分,这将为您提供所需的结果。考虑到可能的更小和更大的表示:


1002.9999 + 0.5 = 1003.4999;     integer part: 1003

1003.0001 + 0.5 = 1003.5001;     integer part: 1003

所以简单地写:


var f float64 = 1.003

fmt.Println(int(f * 1000 + 0.5))

把它包装成一个函数:


func toint(f float64) int {

    return int(f + 0.5)

}


// Using it:

fmt.Println(toint(f * 1000))

在Go Playground上试试。


笔记:


在负数的情况下应用它时要小心!例如,如果您的值为-1.003,那么您可能希望结果为-1003。但是如果你添加0.5它:


-1002.9999 + 0.5 = -1002.4999;     integer part: -1002

-1003.0001 + 0.5 = -1002.5001;     integer part: -1002

因此,如果您有负数,则必须:


减去0.5而不是添加

或从结果中0.5加减1

将其合并到我们的辅助函数中:


func toint(f float64) int {

    if f < 0 {

        return int(f - 0.5)

    }

    return int(f + 0.5)

}


查看完整回答
反对 回复 2021-11-15
?
鸿蒙传说

TA贡献1865条经验 获得超7个赞

正如 Will 提到的,这归结为浮动在各种平台上的表示方式。本质上,您需要舍入浮点数,而不是让默认的截断行为发生。对此没有标准库函数,可能是因为有很多可能的行为,而且实现起来很简单。


如果你知道你总是有描述的那种错误,你稍微低于(1299.999999)所需的值(1300.00000),你可以使用数学库的Ceil函数:


f := 1.29999

n := math.Ceil(f*1000)

但是,如果您有不同类型的浮动错误并想要更一般的排序行为?使用数学库的Modf函数用小数点分隔浮点值:


f := 1.29999


f1,f2 := math.Modf(f*1000)

n := int(f1) // n = 1299   

if f2 > .5 { 

    n++

}

fmt.Println(n)

您可以自己在操场上运行此代码的稍微更通用的版本。


查看完整回答
反对 回复 2021-11-15
?
临摹微笑

TA贡献1982条经验 获得超2个赞

这可能是大多数编程语言中浮点的一般问题,尽管有些语言的实现与其他语言不同。我不会在这里讨论错综复杂的问题,但大多数语言通常都采用“十进制”方法作为标准库或第三方库以获得更高的精度。


例如,我发现inf.v0包非常有用。库的底层是一个Dec结构体,它保存指数和整数值。因此,它能够保持1.003为1003 * 10^-3。请参阅下面的示例:


package main


import (

    "fmt"


    "gopkg.in/inf.v0"

)


func main() {

    // represents 1003 * 10^-3

    someDec := inf.NewDec(1003, 3)


    // multiply someDec by 1000 * 10^0

    // which translates to 1003 * 10^-3 * 1000 * 10^0

    someDec.Mul(someDec, inf.NewDec(1000, 0))


    // inf.RoundHalfUp rounds half up in the 0th scale, eg. 0.5 rounds to 1

    value, ok := someDec.Round(someDec, 0, inf.RoundHalfUp).Unscaled()

    fmt.Println(value, ok)

}

希望这可以帮助!


查看完整回答
反对 回复 2021-11-15
  • 3 回答
  • 0 关注
  • 341 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信