LINUX.ORG.RU

Округление в Go

 


0

1

Почему так?

package main

import (
	"fmt"
	"strconv"
)

func main() {
	fmt.Println(strconv.FormatFloat(0.15, 'f', 1, 32)) // печатает 0.2
	fmt.Println(strconv.FormatFloat(0.15, 'f', 1, 64)) // печатает 0.1
}

http://play.golang.org/p/MeAc6vXCnC

В документации написано, что

FormatFloat converts the floating-point number f to a string, according to the format fmt and precision prec. It rounds the result assuming that the original was obtained from a floating-point value of bitSize bits (32 for float32, 64 for float64).

Будет ли всегда корректно округлять такая функция?

package main

import (
	"fmt"
	"math"
	"strconv"
)

func Round(num float64, digits int) float64 {
	str := strconv.FormatFloat(float64(num), 'f', digits+1, 64)
	str, c := str[:len(str)-1], str[len(str)-1]
	f, _ := strconv.ParseFloat(str, 64)
	if c >= '5' && c <= '9' {
		f += 1 / math.Pow10(digits)
	}
	return f
}

func main() {
	fmt.Println(Round(0.15, 1))
}

Лучший вариант?

discordia
() автор топика
Ответ на: комментарий от discordia

Для начала тебе стоит почитать про представление чисел с плавающей точкой и узнать, почему 0.15 != 0.15.

korvin_ ★★★★★
()
Ответ на: комментарий от korvin_

Я в курсе, на самом деле. Хотелось бы иметь в Go нормальную арифметику с фиксированной точкой. Есть какие-нибудь библиотеки?

discordia
() автор топика
Ответ на: комментарий от discordia

Отвечу сам себе. Нет, это некорректно работает, например, с числом 0.146

discordia
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.