2017-01-26 13 views
0

Я написал метод для многочленного длинного деления. И он отлично работает с «хорошими» полиномами. Под «хорошим» я имею в виду коэффициенты, которые делятся точными. Сегодня я столкнулся с проблемой, когда пытался разделить 2*x^3-18*x^2+..../7.00000(much zeros)0000028*x^2 + 5*x + ... После деления 2*x^3/7.000...000028*x^2 я получил 0.285714....53*x. На следующем шаге нам нужно умножить 0.2857....53*x на 7.00000...0000028*x^2 + 5*x + .. и вычесть его из дивидендного полинома 2*x^3-18*x^2+... и получить новый многочлен со степенью = 2. Но из-за проблемы с double тип I фактически получил полиномиальный 2.220....E-16*x^3 - 6*x^2 + .... Я знаю, что он фактически равен нулю около x^3. Я не хочу изобретать что-то новое и странное, поэтому я спрашиваю, как его решить красиво и правильно. Благодарю.двойные номера не слишком точны

+0

Да, они в точности, тоже плавают. Вы хотите получить ответы, попробуйте прочитать, как поплавки закодированы на вашем языке программирования. –

+1

Вы всегда можете попробовать что-то вроде https://gmplib.org/manual/Floating_002dpoint-Functions.html, если вам нужна более высокая точность, чем обычные двойные предложения. – Paladin

+0

@MaazRehman и как он мне поможет? – danielleontiev

ответ

2

Многие результаты разделения, такие как 1/7, не могут быть представлены точно в двойном или BigDecimal. Если вы идете с BigDecimal, вам нужно будет выбрать несколько цифр для сохранения и обработать ошибку округления. Для double вы получаете более удобную арифметику, но фиксированное количество значимых бит.

У вас есть два варианта.

Один из них предназначен для обработки ошибки округления. Когда результат очень близок к нулю, так близко, что, вероятно, из-за ошибки округления, обрабатывайте его как ноль. Я не знаю, будет ли это работать для вашего алгоритма или нет. Если вы пройдете этот путь, вы можете использовать либо double, либо BigDecimal.

Второй вариант - использовать пакет рационального числа. В арифметике рационального числа все результаты разделения могут быть представлены точно. 1/7 остается 1/7, без округления до конечной десятичной или двоичной фракции. Если вы идете по этому пути, найдите «рациональное число java» (без кавычек) и решите, какой из них вам больше всего нравится.