英文:
How to count decimal places of float?
问题
我想检查一个float32是否有两位小数。我在JavaScript中的做法如下:
step := 0.01
value := 9.99
if int(value/step) % 1 == 0 {
printf("有两位小数!")
}
上面的例子也是有效的。然而,当step不正确时,它将无法正常将float64转换为int。
例如:
step := 0.1
value := 9.99
if int(value/step) % 1 == 0 {
printf("有两位小数!")
}
编译错误:常量9.99被截断为整数
当我们使用动态值时,它将对每种情况返回true。
那么,计算小数位数的适当方法是什么?
英文:
I want to check if a float32 has two decimal places or not. My javascript way to do this would look like:
step := 0.01
value := 9.99
if int(value/step) % 1 == 0 {
printf("has two decimal places!")
}
The above example also works. However it will not work when step is incorrect as go then cannot properly cast from float64 to int.
Example:
step := 0.1
value := 9.99
if int(value/step) % 1 == 0 {
printf("has two decimal places!")
}
Compiler Error: constant 9.99 truncated to integer
When we use dynamic values it will just return true for every case.
So what is the appropriate way to count decimal places?
答案1
得分: 9
你必须进行一些技巧性的操作,添加一个额外的变量:
step := 0.1
value := 9.99
steps := value / step
if int(steps)%1 == 0 {
fmt.Println("有两位小数!")
}
或者在将 steps 转换为 int 之前先将其转换为 float64,例如:
int(float64(value / step))
//编辑
一种不太正规的非数学方法是将其转换为字符串并进行拆分,例如:
func NumDecPlaces(v float64) int {
s := strconv.FormatFloat(v, 'f', -1, 64)
i := strings.IndexByte(s, '.')
if i > -1 {
return len(s) - i - 1
}
return 0
}
//使用了一个小的优化进行更新
英文:
You have to trick it, add an extra variable:
step := 0.1
value := 9.99
steps := value / step
if int(steps)%1 == 0 {
fmt.Println("has two decimal places!")
}
Or cast your steps before you convert it to int like:
int(float64(value / step))
//edit
the hacky non-mathematical way is to convert it to a string and split it, example:
func NumDecPlaces(v float64) int {
s := strconv.FormatFloat(v, 'f', -1, 64)
i := strings.IndexByte(s, '.')
if i > -1 {
return len(s) - i - 1
}
return 0
}
//updated with a minor optimization
答案2
得分: 2
这是一个用于获取浮点数小数部分的函数。可以使用len(decimalPortion(n))
来获取小数位数。
func decimalPortion(n float64) string {
decimalPlaces := fmt.Sprintf("%f", n-math.Floor(n)) // 生成 0.xxxx0000
decimalPlaces = strings.Replace(decimalPlaces, "0.", "", -1) // 移除 0.
decimalPlaces = strings.TrimRight(decimalPlaces, "0") // 移除尾部的 0
return decimalPlaces
}
在playground中查看。
英文:
Here's a function to get the decimal portion of a float. Can use len(decimalPortion(n))
to get the number of decimal places.
func decimalPortion(n float64) string {
decimalPlaces := fmt.Sprintf("%f", n-math.Floor(n)) // produces 0.xxxx0000
decimalPlaces = strings.Replace(decimalPlaces, "0.", "", -1) // remove 0.
decimalPlaces = strings.TrimRight(decimalPlaces, "0") // remove trailing 0s
return decimalPlaces
}
Check it out in playground
答案3
得分: 1
int value % 1 is always zero!
我建议另一种方法:
value := float32(9.99)
valuef := value*100
extra := valuef - float32(int(valuef))
if extra < 1e-5 {
fmt.Println("有两位小数!");
}
http://play.golang.org/p/LQQ8T6SIY2
更新
package main
import (
"math"
)
func main() {
value := float32(9.9990001)
println(checkDecimalPlaces(3, value))
}
func checkDecimalPlaces(i int, value float32) bool {
valuef := value * float32(math.Pow(10.0, float64(i)))
println(valuef)
extra := valuef - float32(int(valuef))
return extra == 0
}
http://play.golang.org/p/jXRhHsCYL-
英文:
int value % 1 is always zero!
I suggest an alternative way:
value := float32(9.99)
valuef := value*100
extra := valuef - float32(int(valuef))
if extra < 1e-5 {
fmt.Println("has two decimal places!");
}
http://play.golang.org/p/LQQ8T6SIY2
Update
package main
import (
"math"
)
func main() {
value := float32(9.9990001)
println(checkDecimalPlaces(3, value))
}
func checkDecimalPlaces(i int, value float32) bool {
valuef := value * float32(math.Pow(10.0, float64(i)))
println(valuef)
extra := valuef - float32(int(valuef))
return extra == 0
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论