I think the right way to solve these issues is not to think about it like a Math problem.
We need to write tests showing bugs and doing lots of coverage. Then, we can look into other programming languages (Java, Ruby, Python, etc), port an implementation and ensure it's correct. This is the kind of things where people have spent days to get right and efficient. The goal is not to figure how to do it better but how to port the best implementation out there. On Wed, Oct 26, 2016 at 9:58 AM, Nicolas Cellier < nicolas.cellier.aka.n...@gmail.com> wrote: > > > 2016-10-26 9:14 GMT+02:00 stepharo <steph...@free.fr>: > >> Hi nicolas >> >> So what is the solution? We can integrate fast a solution. >> I would really like to see them fix in Pharo 60. >> I'm writing a book for newbie and this is the third time I change one >> chapter >> so may be I should stop and throw away this chapter. >> >> > 1) for Fraction: > > round: numberOfWishedDecimal > v := 10 raisedTo: numberOfWishedDecimal. > ^ ((self * v) rounded / v) asFloat > > or just replace asFloat if you wish to remain exact: > > round: numberOfWishedDecimal > v := 10 raisedTo: numberOfWishedDecimal. > ^ ((self * v) rounded / v) asScaledDecimal: numberOfWishedDecimal > > 2) for Float, it is in 15471: > > round: numberOfWishedDecimal > | v maxNumberOfDecimals | > maxNumberOfDecimals := self class precision - 1 - (self exponent max: > self class emin). > maxNumberOfDecimals < numberOfWishedDecimal ifTrue: [^self]. > v := 10 raisedTo: numberOfWishedDecimal. > ^ ((self asFraction * v) rounded / v) asFloat > > or if Fraction already answers a Float: > > round: numberOfWishedDecimal > | maxNumberOfDecimals | > maxNumberOfDecimals := self class precision - 1 - (self exponent max: > self class emin). > maxNumberOfDecimals < numberOfWishedDecimal ifTrue: [^self]. > ^ self asFraction round: numberOfWishedDecimal > > It's slower than current implementation, but will round exactly to the > nearest Float. > It's possible to have faster implementation up to 22 decimals if you > provide a fused-multiply-accumulate primitive... > > > You see I'm not good in math so even if I try hard I will not have a good >> solution. >> This is the same for marcus and most people in our team. >> I reopened these issues. >> >> Stef >> >> >> >> 2016-10-25 23:22 GMT+02:00 stepharo <steph...@free.fr>: >> >>> Ok for the advice >>> >>> Now round: aNumberOfDigits seems to work fine. >>> >>> Stef >>> >>> >> No it's not, but issues are timing out too fast ;) >> https://pharo.fogbugz.com/f/cases/15471/Can-t-round-Float-fm >> ax-to-2-decimal-places >> https://pharo.fogbugz.com/f/cases/15472/Fraction-rounding-to >> -n-decimal-places-is-inexact >> https://pharo.fogbugz.com/f/cases/15473/Float-round-to-n-dec >> imal-places-is-not-in-agreement-with-printShowingDecimalPlaces >> >> I hate to say that, but try in python, they got it right... >> >> >> >>> Le 25/10/16 à 11:05, Henrik Johansen a écrit : >>> >>> +1. >>> >>> Unless you're dealing with fixed precision* entities, it's usually >>> better to specify digits to display in printing methods themselves >>> (#printShowingDecimalPlaces: & friends in base image). >>> As per previous discussions around this that arise every second year or >>> so, rounding the number itself (as long as we're dealing with floats) will >>> never work as you want reliably. >>> >>> Cheers, >>> Henry >>> >>> * And in that case, you'd use ScaledDecimals >>> >>> On 23 Oct 2016, at 7:08 , p...@highoctane.be wrote: >>> >>> I use the Printf package for that. >>> >>> v := 65.456. >>> 'With 2 decimal digits: %5.2f, or 3 like this: %6.3f' >>> printf: {v. v}. >>> >>> With 2 decimal digits: 65.45, or 3 like this: 65.456 >>> >>> It is in http://www.smalltalkhub.com/#!/~philippeback/HOExtras >>> >>> Printf >>> >>> I am just used to C printf and well, I like the way it works. >>> >>> Phil >>> >>> >>> >> >> >