我正在寻找要舍入到Golang中最接近的0.05的函数 。使用该函数的最终结果必须始终为0.05的因数。
以下是我要查找的功能的一些输出示例:(该功能Round还不存在,我希望可以将其包含在答案中)
Round(0.363636) // 0.35
Round(3.232) // 3.25
Round(0.4888) // 0.5
我已经搜索了很长时间,但是没有找到任何答案。
前言:
我在中发布了此实用程序github.com/icza/gox
,请参见mathx.Round()
。
Go
1.10已发布,并添加了math.Round()
功能。此函数四舍五入到最接近的整数(基本上是
“四舍五入至1.0” 运算),使用它我们可以很容易地构造一个四舍五入到所选单位的函数:
func Round(x, unit float64) float64 {
return math.Round(x/unit) * unit
}
测试它:
fmt.Println(Round(0.363636, 0.05)) // 0.35
fmt.Println(Round(3.232, 0.05)) // 3.25
fmt.Println(Round(0.4888, 0.05)) // 0.5
fmt.Println(Round(-0.363636, 0.05)) // -0.35
fmt.Println(Round(-3.232, 0.05)) // -3.25
fmt.Println(Round(-0.4888, 0.05)) // -0.5
在Go Playground上尝试一下。
原始答案如下,该答案是在Go
1.10之前创建的(不math.Round()
存在时),并且还详细说明了自定义Round()
函数背后的逻辑。在这里出于教育目的。
在Go1.10之前的时代没有math.Round()
。但…
舍入任务可以很容易地通过float64
=> int64
转换来实现,但是必须小心,因为float到int的转换 不是舍入而是保留整数部分。
例如:
var f float64
f = 12.3
fmt.Println(int64(f)) // 12
f = 12.6
fmt.Println(int64(f)) // 12
12
在两种情况下,结果都是整数部分。要获取四舍五入的“功能”,只需添加0.5
:
f = 12.3
fmt.Println(int64(f + 0.5)) // 12
f = 12.6
fmt.Println(int64(f + 0.5)) // 13
到目前为止,一切都很好。但是我们不想舍入到整数。如果我们想四舍五入到小数点后一位,则在添加0.5
和转换之前将乘以10 :
f = 12.31
fmt.Println(float64(int64(f*10+0.5)) / 10) // 12.3
f = 12.66
fmt.Println(float64(int64(f*10+0.5)) / 10) // 12.7
因此,基本上,您要乘以要舍入的单位的倒数。要舍入为0.05
单位,请乘以1/0.05 = 20
:
f = 12.31
fmt.Println(float64(int64(f*20+0.5)) / 20) // 12.3
f = 12.66
fmt.Println(float64(int64(f*20+0.5)) / 20) // 12.65
将其包装为一个函数:
func Round(x, unit float64) float64 {
return float64(int64(x/unit+0.5)) * unit
}
使用它:
fmt.Println(Round(0.363636, 0.05)) // 0.35
fmt.Println(Round(3.232, 0.05)) // 3.25
fmt.Println(Round(0.4888, 0.05)) // 0.5
在Go Playground上尝试示例。
需要注意的是四舍五入3.232
有unit=0.05
不准确打印3.25
,但0.35000000000000003
。这是因为float64
数字使用称为IEEE-754标准的有限精度进行存储。
另请注意,它unit
可以是“任何”数字。如果为1
,则Round()
基本上四舍五入为最接近的整数。如果为10
,则四舍五入为0.01
十进制;如果为,则四舍五入为2个小数位。
还要注意,当您Round()
使用负数拨打电话时,您可能会得到令人惊讶的结果:
fmt.Println(Round(-0.363636, 0.05)) // -0.3
fmt.Println(Round(-3.232, 0.05)) // -3.2
fmt.Println(Round(-0.4888, 0.05)) // -0.45
这是因为-如前所述,转换将保留整数部分,例如-1.6
is的整数部分-1
(大于-1.6
;而1.6
is的整数部分1
小于1.6
)。
如果要-0.363636
成为-0.35
而不是-0.30
,则在负数的情况下在函数内部添加-0.5
而不是。请参阅我们改进的功能:0.5``Round()``Round2()
func Round2(x, unit float64) float64 {
if x > 0 {
return float64(int64(x/unit+0.5)) * unit
}
return float64(int64(x/unit-0.5)) * unit
}
并使用它:
fmt.Println(Round2(-0.363636, 0.05)) // -0.35
fmt.Println(Round2(-3.232, 0.05)) // -3.25
fmt.Println(Round2(-0.4888, 0.05)) // -0.5
编辑:
为了解决您的评论:由于您不喜欢“不精确” 0.35000000000000003
,因此建议将其格式化并重新解析为:
formatted, err := strconv.ParseFloat(fmt.Sprintf("%.2f", rounded), 64)
而这种“貌似”的结果与打印出来的结果0.35
完全一样。
但这只是一个“幻想”。由于0.35
不能使用IEEE-754标准用有限的位表示,因此处理该数字也没关系,如果将其存储在type值中float64
,则该数字将不是完全正确的0.35
(但是IEEE-754数字非常接近对此)。您看到的是将其fmt.Println()
打印出来,0.35
因为fmt.Println()
已经进行了一些四舍五入。
但是,如果您尝试以更高的精度打印它:
fmt.Printf("%.30f\n", Round(0.363636, 0.05))
fmt.Printf("%.30f\n", Round(3.232, 0.05))
fmt.Printf("%.30f\n", Round(0.4888, 0.05))
输出:不好(可能更难看):在Go Playground上尝试:
0.349999999999999977795539507497
3.250000000000000000000000000000
0.500000000000000000000000000000
注意,另一方面,3.25
和0.5
是精确的,因为它们可以精确地用有限位表示,因为用二进制表示:
3.25 = 3 + 0.25 = 11.01binary
0.5 = 0.1binary
有什么教训?格式化和重新解析结果是不值得的,因为它也不是精确的(只是一个不同的float64
值(根据默认的fmt.Println()
格式化规则)在打印时可能会更好)。如果您想要好的打印格式,则只需进行精确的格式化即可,例如:
func main() {
fmt.Printf("%.3f\n", Round(0.363636, 0.05))
fmt.Printf("%.3f\n", Round(3.232, 0.05))
fmt.Printf("%.3f\n", Round(0.4888, 0.05))
}
func Round(x, unit float64) float64 {
return float64(int64(x/unit+0.5)) * unit
}
这将是准确的(在Go Playground上尝试):
0.350
3.250
0.500
或者只是将它们相乘100
并使用整数,这样就不会发生任何表示或舍入错误。
问题内容: 我可以在python中进行以下舍入: 四舍五入到最接近的05小数 7,97-> 7,95 6,72-> 6,70 31,06-> 31,05 36,04-> 36,05 5,25-> 5,25 希望有道理。 问题答案:
问题内容: 我试图找到一种方法将值四舍五入到最接近的0.05。例如: 0.93四舍五入为0.95 0.81四舍五入为0.80 0.65停留0.65 0.68至0.70 0.67至0.65 用Java有没有简单的方法可以做到这一点? 问题答案: 一种选择如下: 将该值乘以20。 使用进行四舍五入为最接近的整数。 再除以20。 例如: 希望这可以帮助!
问题内容: 我想将a舍入到最接近的10的倍数。 例如,如果数字为8.0,则四舍五入为10。如果数字为2.0,则将其四舍五入为0。 我怎样才能做到这一点? 问题答案: 您可以使用函数(将浮点数四舍五入到最接近的整数值)并应用“比例因子” 10: 用法示例: 在第二个示例中,除以十(),四舍五入(),转换为整数(),然后再乘以10()。 斯威夫特3: 或者:
问题内容: 我来到了Java程序的一部分,我需要四舍五入到最接近的百位数,并认为可能有某种方法可以做到这一点,但我想没有。因此,我在网上搜索了示例或任何答案,但由于所有示例看起来都接近最接近的一百,因此至今仍未找到任何答案。我只想这样做并向上取整。也许有一些我忽略的简单解决方案。我已经尝试了其他功能,但到目前为止还没有找到答案。如果有人可以帮助我解决这个问题,我将不胜感激。 如果我的电话号码是20
问题内容: 我正在尝试在python中舍入整数。我看了内置的round()函数,但似乎舍入浮动了。 我的目标是将整数四舍五入到最接近的10的倍数。即:5-> 10、4-> 0、95-> 100,等等。 5和更高的值应四舍五入,4和更低的值应四舍五入。 这是我这样做的代码: 这是实现我想要实现的最好方法吗?有内置的功能吗?另外,如果这是最好的方法,那么我在测试中遗漏的代码是否有问题? 问题答案: 实
问题内容: 这个问题已经在这里有了答案 : 使用Python 3打印时出现语法错误[重复] (3个答案) 5年前关闭。 我想将整数四舍五入为最接近的0.25个十进制值,如下所示: 这给我Python中的以下错误: 问题答案: 该功能不存在,仅使用内置 请注意,这是Python 3中的函数,因此必须加括号。 目前,您的函数未返回任何内容。从函数中返回值而不是打印它可能更好。 如果要舍入,请使用。