Error in the org.jorlib.alg.packing.circlePacking.util.sqrt(BigDecimal squarD, MathContext rootMC) method.
Dear Joris,
I've found that sqrt() method for BigDecimals sometimes not comply its contract.
For example,
let exactSqrt be BigDecimal represented by the string
String str = "0.352818528921979802147666515426902895727765101266038472739273675725801740461899203391467404999652538893639944052164993861983322930689421050680216977023059231670566602635420201308103469059177274411042449967235640170639404861525798685782654348576008053906678123883330032297238500985193573602497626771580945594770502324168762166567267289269665176402913948019856635315861428993880073282624381118485716289019571647659739495016074896218885978289930340857274515862259731833170589692399895634244147482703269890913247408478923447178902017779845443742308844558419999046111467812933248023432427998259994182648578288775189490102071574925542172618705808377981407075661662506742408661232720032172324989308087757531861080580705851938971046656424285025030048776692043487994681169121806548569325273977674268512834848319197541770346893931298171263359209287656256258646644947830231869419567842967424731270811652666974200603722897904972781881580215186731799243387581020765695927222985513092811072096813507351486163616474354491678516423019462856092324589467805417576434369118271125610599862858091034066115393896376402586115322883185629500789989825539099146963464597667690086645833677773341477425089421202029845828438186267290619982627882863531585505515611951359679835295645460495124946561810293085634756353824263832486284294130150330118760419800451287490407783325022093281030504666007839427958453674663221723404057631681719148427415412519993998928227188905950986505087130321733361332156307945821264095564986339643413952656671077302618008809419170629325044973291573447163149540989060334863465155227701549160360633076458829101325288181727254148455952801479839414624838237422509188727938777531618602609770842427633605357541405468766390741255444162263154213109493016536875507122768177992567211419631697956177013676147279765005362827247748175113476912061656596560057107219180031161086243871513570693257886733246854019430780326947936432096164343749503593404634630874853900858530925398333908462443249715617740821018862850469001766145798985952338158907879181848149273610535411146431164860190045987407079776737665145855618269772150097545656533084155333408671462357567952863327464733354130776616979840611935007402670571489089668548000566788250160846791012993775567439582182725205696062583108329707566149812378805220075179590531688600283608991116551549027626948019331454835003314143801424170814628183200055052199722542207640173290280989264977286415610857154441019808138140819856280410105031134448183196991569236564590128053475070955652666628369465344771805924916499026673246861918192823814334395024295138823232784709065496229159508579419100068387896656615250289291758465598666278370085239497533286365488975303055116815329102108942419789159408743304837147769168826679563309806682084876882871097306440805958691670681692306549364491345283413772350464609125873897690388407474850326909999101415928102266360806164931776847358063319741306986987628745641280473524000212369792965384091797156403233777795567784543089119411659393168440334248938741623001128517522693879403929699173451781412798671665283558729628243926890969910443705973489192155576353499381779194610671587110478486168711282156757950565546363036019684717556713624143788093810345688751549193665721896867887651320967000222128167164946865556889602661431879227060777814881492519547779448310707438750917861990561928144098861424157634058497094462991766917173509132343518475084202673630176061598854141914185610767706802039701642072360625842378688027735898240182190514393189209471611768527100950310316851880853478199424580668628085693182998731100236819825441203790704941193496754099933586278887732102406442366897274992111227286780538771607254703391727435908633086669314433562019482301856480278389899972125503889024035852303562592479624352423337002906871575935923566494087298753092343486998023539344694510533797805958900582731852193990439519387549384829431113980579322708657363957164395621754828226758348067425530114629280261288667931574298350041682965467047588359489270073143306999546737192711175822029705263447027865758551542802171488905955004349464501480093234324812778987292165459441941026474022142289145222953357220372418411212413061286574450794826437795190069128780886322873705075391534786287589843850190532006721823083493988784719966839685662262264057458858102263578441838880872379410128677308321014897665822450598742323482617706556668314972948257303337118691806018319646689269303327895611192483290610412447084434138915732180208661257866451990865563784573699574180113438083551175839547069343207045045995100912147324966281922502715105823762488576030121131547913526483123729519773892343318565326104868289395276455971388735259382226159413912984029551781738507760341551002029698244452208252501876382885200201519676863857276544629621043623553022169433277290829018245988763416544714675486727259277158207185683059120469903788050023125005340124434545488528442744313808998213896416775571508334831773577301265300131926124116720552814768332474881127016239632373827247236037212368475176197284063580380941316779730166327775936730580436889438218610438044839337499052077613183040131513844261362138421340482537949355008184657331131802878928188016227607049663793923496957161690184263051610305144160357410316194354127288952746801158072255627528356254285419729629914150135164293325498786148924752199146507320087447951639563162872093511891508859874602833528357633853230657750414976922360211994756093221208726220406868776436423802282853111630343720137345935295997001814433021729906260871559252222785750795910525236903608970515342971450150471140143424730302419832493045288822449089904121958127502411554916890000523296881346660246083743133530717406880789993705668249624474982096681744820733458578119329965309671669003956057605867177163829210966938191726511853645119095575338547037668182994797666943720389432824576727544324133629219070818056301690488891414444637139445286226789026200554535161974614349396819623126119487492383584029405209572120869911038247087356343641894799034464020392552038747499914221074709047988903494270079315963932888035593068602395612879290719088991015317352105164692480211676756550307172096101637696730714405029471608453893636023178565563010040550935381304155988922549067016051209896944367217070301142516901257757847663657027699473130521129513917273661361656490890291200300878354926042615514456147252662943337364841398596952462369372282916304134920158141647180675038504459880237319";
Then the code:
BigDecimal exactSqrt = new BigDecimal(str);
BigDecimal number = exactSqrt.multiply(exactSqrt);
MathContext mathContext = new MathContext(exactSqrt.precision() + 1, RoundingMode.HALF_UP);
BigDecimal rounded = exactSqrt.round(mathContext);
BigDecimal sqrt = MathUtil.sqrt(number, mathContext);
BigDecimal difference = rounded.subtract(sqrt);
BigDecimal scaledDifference = difference.scaleByPowerOfTen(difference.scale());
System.out.println("Scaled difference: " + scaledDifference.toPlainString());
produces
Scaled difference: -465100 instead of zero.
Hi Mikhail, Thanks for reporting this. This Math Utility was originally contributed by Frans Lelieveld, so I'm not very familiar with its implementation. Would you be able (and willing) to look into this issue and see whether this is actually a bug in the code, or for example a rounding issue? Your input is a very long number, and the scaled difference seems very small compared to the very big number you put in, so I wouldn't be surprised if this issue is caused by rounding.
Hi Joris! I think that the actual problem is the stoppage criterion for the iteration method used by Frans. I've examined the book used as source of the algorithm, and I found that the original implementation in the book differs from the Frans's implementation. Another factor is that Frans guarantees correct rounding with provided MathContext. But this it is not as simple as appears. In fact the algorithm needs more accurate theoretical investigation before its robust implementation will be possible.
Best regards, Mikhail.
Joris, I found that the method gives wrong answer for the number 4 * 10^74 + 1 with rounding mode UP. The square root of this number exceeds 2 * 10^37, so correct UP rounding with 1 digit precision should be the number 3 * 10^37. But
BigDecimal number = new BigDecimal(new BigInteger("4"), -74).add(BigDecimal.ONE);
mathContext = new MathContext(1, RoundingMode.UP);
System.out.println(MathUtil.sqrt(number, mathContext).toPlainString());
produces 2E+37.
Hm I agree with your example. It seems that this error occurs with very tiny numbers. Given that you were able to study the book which was used to implement this algorithm, would you be able to spot the implementation issue? The book refers to an implementation itsqrt.cc, which you can find on the publisher's website: http://extras.springer.com/2001/978-3-642-56735-3/hfloat/hfloat/src/hf/itsqrt.cc The first line states: "#warning 'sqrt_iteration() is experimental (loss of precision !)'". So I'm not surprised that you encounter precision errors with such small numbers. Here's another implementation: https://github.com/rizar/matrix/blob/master/src/com/github/rizar/bigdecimalmath/BigDecimalMath.java Does this one have similar issues? I'm happy to help you out wherever I can, but I have very little knowledge about this specific domain...
Joris
On Fri, Apr 22, 2016 at 9:40 AM, Mikhail Zvagelsky <[email protected]
wrote:
Joris, I found that the method gives wrong answer for the number 4 * 10^74 + 1 with rounding mode UP. The square root of this number exceeds 2
- 10^37, so correct UP rounding with 1 digit precision should be the number 3 * 10^37. But
BigDecimal number = new BigDecimal(new BigInteger("4"), -74).add(BigDecimal.ONE); mathContext = new MathContext(1, RoundingMode.UP); System.out.println(MathUtil.sqrt(number, mathContext).toPlainString());
produces 2E+37.
— You are receiving this because you commented. Reply to this email directly or view it on GitHub https://github.com/jkinable/jorlib/issues/4#issuecomment-213431613