3 回答
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)
}
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)
您可以自己在操场上运行此代码的稍微更通用的版本。
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)
}
希望这可以帮助!
- 3 回答
- 0 关注
- 341 浏览
添加回答
举报