Как считать десятичные разряды с плавающей точкой?
Я хочу проверить, имеет ли float32 два десятичных знака или нет. Мой способ JavaScript сделать это будет выглядеть так:
step := 0.01
value := 9.99
if int(value/step) % 1 == 0 {
printf("has two decimal places!")
}
Приведенный выше пример также работает. Однако это не будет работать, если шаг неверен, поскольку go не может правильно привести тип из float64 к int.
Пример:
step := 0.1
value := 9.99
if int(value/step) % 1 == 0 {
printf("has two decimal places!")
}
Ошибка компилятора: constant 9.99 truncated to integer
Когда мы используем динамические значения, он просто возвращает true для каждого случая.
Итак, как правильно считать десятичные разряды?
2 ответа
Значение int% 1 всегда равно нулю!
Я предлагаю альтернативный способ:
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
Обновить
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
}
Вы должны обмануть это, добавить дополнительную переменную:
step := 0.1
value := 9.99
steps := value / step
if int(steps)%1 == 0 {
fmt.Println("has two decimal places!")
}
Или приведите свои шаги перед тем, как преобразовать его в тип int:
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
}
// обновлено с небольшой оптимизацией
Вот функция для получения десятичной части числа с плавающей точкой. Можешь использовать len(decimalPortion(n))
чтобы получить количество знаков после запятой.
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
}