Я столкнулся с интересной проблемой вычисления big.Float в Голанге.
Проблема в
10001000100010001000100010001000100010001000100015,5533 / 10000000000000000000
= 10001000100010001000100010001000.1000100010001000155533
Тем не менее, big.Float дал «10001000100010001000100010001000,10001000100010001555329999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999997»
Код:
var prec uint = 1024 // 512
dec, _ := new(big.Float).SetPrec(prec).SetString("1000000000000000000")
f, _ := new(big.Float).SetPrec(prec).SetString("10001000100010001000100010001000100010001000100015.5533")
q := f.Quo(f, dec)
fmt.Printf("Percision: %d\n", prec)
fmt.Printf("Quotient: %s\n", q.Text('f', -1))
Результат:
Percision: 1024
Quotient: 10001000100010001000100010001000.10001000100010001555329999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999997
И что еще более запутанно, если я установил prec = 512, меньшую точность, вместо этого он дал правильный результат.
Percision: 512
Quotient: 10001000100010001000100010001000.1000100010001000155533
Кто-нибудь знает, что не так с моим кодом или как настроить big.Float для получения ожидаемого результата?
Спасибо всем!

От go doc math/big.Float:
A nonzero finite Float represents a multi-precision floating point number
sign × mantissa × 2**exponent
with 0.5 <= mantissa < 1.0, and MinExp <= exponent <= MaxExp.
И SetPrec устанавливает битовую ширину мантиссы, а не какую-то десятичную точность.
Как и в случае с float64, не каждое десятичное число может быть точно представлено в big.Float, и ваш код показывает это. Тот факт, что вы видите то, что ожидаете увидеть с prec=512, связан с различным округлением и печатью.
Эмпирическое правило: big.Floats ведут себя как «нормальные» float со всеми их недостатками (здесь не каждая десятичная дробь может быть представлена), но могут показывать меньше ошибок округления.