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

我想转换一个float64数字,让我们也说1.003要1003(整型)。我的实现只是将float64with相乘1000并将其转换为int.


package main


import "fmt"



func main() {

  var f float64 = 1.003

  fmt.Println(int(f * 1000))

}

但是当我运行该代码时,我得到的1002不是1003. 因为 Go 自动将1.003as存储1.002999...在变量中。在 Golang 上做这种操作的正确方法是什么?


慕莱坞森
浏览 342回答 3
3回答

慕码人2483693

Go规范:转换:数字类型之间的转换将浮点数转换为整数时,分数将被丢弃(向零截断)。所以基本上当你将浮点数转换为整数时,只保留整数部分。如果您只是想避免因用有限位表示而产生的错误,只需0.5在将其转换为int. 不需要外部库或函数调用(来自标准库)。由于float -> int转换不是四舍五入而是保留整数部分,这将为您提供所需的结果。考虑到可能的更小和更大的表示:1002.9999 + 0.5 = 1003.4999;&nbsp; &nbsp; &nbsp;integer part: 10031003.0001 + 0.5 = 1003.5001;&nbsp; &nbsp; &nbsp;integer part: 1003所以简单地写:var f float64 = 1.003fmt.Println(int(f * 1000 + 0.5))把它包装成一个函数:func toint(f float64) int {&nbsp; &nbsp; 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;&nbsp; &nbsp; &nbsp;integer part: -1002-1003.0001 + 0.5 = -1002.5001;&nbsp; &nbsp; &nbsp;integer part: -1002因此,如果您有负数,则必须:减去0.5而不是添加或从结果中0.5加减1将其合并到我们的辅助函数中:func toint(f float64) int {&nbsp; &nbsp; if f < 0 {&nbsp; &nbsp; &nbsp; &nbsp; return int(f - 0.5)&nbsp; &nbsp; }&nbsp; &nbsp; return int(f + 0.5)}

鸿蒙传说

正如 Will 提到的,这归结为浮动在各种平台上的表示方式。本质上,您需要舍入浮点数,而不是让默认的截断行为发生。对此没有标准库函数,可能是因为有很多可能的行为,而且实现起来很简单。如果你知道你总是有描述的那种错误,你稍微低于(1299.999999)所需的值(1300.00000),你可以使用数学库的Ceil函数:f := 1.29999n := math.Ceil(f*1000)但是,如果您有不同类型的浮动错误并想要更一般的排序行为?使用数学库的Modf函数用小数点分隔浮点值:f := 1.29999f1,f2 := math.Modf(f*1000)n := int(f1) // n = 1299&nbsp; &nbsp;if f2 > .5 {&nbsp;&nbsp; &nbsp; n++}fmt.Println(n)您可以自己在操场上运行此代码的稍微更通用的版本。

临摹微笑

这可能是大多数编程语言中浮点的一般问题,尽管有些语言的实现与其他语言不同。我不会在这里讨论错综复杂的问题,但大多数语言通常都采用“十进制”方法作为标准库或第三方库以获得更高的精度。例如,我发现inf.v0包非常有用。库的底层是一个Dec结构体,它保存指数和整数值。因此,它能够保持1.003为1003 * 10^-3。请参阅下面的示例:package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "gopkg.in/inf.v0")func main() {&nbsp; &nbsp; // represents 1003 * 10^-3&nbsp; &nbsp; someDec := inf.NewDec(1003, 3)&nbsp; &nbsp; // multiply someDec by 1000 * 10^0&nbsp; &nbsp; // which translates to 1003 * 10^-3 * 1000 * 10^0&nbsp; &nbsp; someDec.Mul(someDec, inf.NewDec(1000, 0))&nbsp; &nbsp; // inf.RoundHalfUp rounds half up in the 0th scale, eg. 0.5 rounds to 1&nbsp; &nbsp; value, ok := someDec.Round(someDec, 0, inf.RoundHalfUp).Unscaled()&nbsp; &nbsp; fmt.Println(value, ok)}希望这可以帮助!
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go