Попробуйте это :
st := 1980.0
f := 0.1 / 1.1
salePrice1 := st * f
salePrice2 := math.Floor(salePrice1)
fmt.Println(salePrice2) // 180
Это большая тема:
Для учетных систем : ответ Плавающийуменьшение точечной ошибки .
(Примечание: один из методов смягчения заключается в использовании int64
, uint64
или big.Int
)
И см .:
Что должен знать каждый компьютерщик об арифметике с плавающей точкой https://en.wikipedia.org/wiki/Double-precision_floating-point_format https://en.wikipedia.org/wiki/IEEE_floating_point
Давайте начнем с:
fmt.Println(1.0 / 3.0) // 0.3333333333333333
IEEE 754 двоичного представления:
fmt.Printf("%#X\n", math.Float64bits(1.0/3.0)) // 0X3FD5555555555555
Двоичное представление IEEE 754 для 1.1:
fmt.Printf("%#X\n", math.Float64bits(1.1)) // 0X3FF199999999999A
fmt.Printf("%#X\n", math.Float64bits(st*0.1/1.1)) // 0X40667FFFFFFFFFFF
Теперь, давайте:
st := 1980.0
f := 0.1 / 1.1
Двоичное представление IEEE 754 для f
:
fmt.Printf("%#X\n", math.Float64bits(f)) // 0X3FB745D1745D1746
И:
salePrice1 := st * f
fmt.Println(salePrice1) // 180
fmt.Printf("%#X\n", math.Float64bits(salePrice1)) // 0X4066800000000000
salePrice2 := math.Floor(salePrice1)
fmt.Printf("%#X\n", math.Float64bits(salePrice2)) // 0X4066800000000000
Работа с числами с плавающей точкой на компьютере не такая же, как с ручкой и бумагой ( Ошибки вычисления с плавающей точкой ):
var st float64 = 1980
var salePrice1 = st * 0.1 / 1.1
fmt.Println(salePrice1) // 179.99999999999997
salePrice1
равно 179,999999999999997, а не 180,0, поэтому целое значение, меньшее или равное 179,999999999999997, равно 179:
См. Документы для func Floor(x float64) float64
:
Floor возвращает наибольшее целое значение, меньшее или равное x.
См .:
fmt.Println(math.Floor(179.999)) // 179
fmt.Println(math.Floor(179.5 + 0.5)) // 180
fmt.Println(math.Floor(179.999 + 0.5)) // 180
fmt.Println(math.Floor(180.0)) // 180
Некоторые соответствующие QAs:
Golang точность с плавающей точкой float32 против float64
Как правильно изменить число с плавающей точкой на uint64?
Golangпреобразование float64 в int ошибка
Не работает ли математика с плавающей запятой?
Сравнение с плавающей запятой
Что делает "% b" в fmt.Printf для float64 и что такое Min субнормальный положительный двойной в float64 в двоичном формате?
Есть ли стандартная библиотека для преобразования float64 в строку с исправлениемширина с максимальным количеством значащих цифр?
fmt.Printf с полями ширины и точности в% g ведет себя неожиданно
Почему есть разницамежду умножением с плавающей запятой с литералами и переменными в Go?
Golang Round to Nearesт 0,05