Hi
I'm wondering if we do not have a bug here 12.222222222222221 roundTo: 0.1 "12.200000000000001" 12.222222222222221 roundTo: 0.01 "12.22" Stef |
I think that's called 'welcome to the wonderfull world of floating points approximations' and not a bug :( See unums/Gustafson for something more interesting on the subject.2016-10-23 18:16 GMT+02:00 stepharo <[hidden email]>: Hi |
I think lisp solves this problem by using integers for its floats , or something along those line, I remember reading about it somewhere when I was studying common lisp 5 years ago Or maybe my memory fails me On Sun, Oct 23, 2016 at 7:24 PM Thierry Goubier <[hidden email]> wrote:
|
In reply to this post by Thierry Goubier
I see. I writing a little example for my new newbies book now how can get only two digits after the .
Stef Le 23/10/16 à 18:23, Thierry Goubier a
écrit :
|
3.1479 roundUpTo: 0.01 is what I was looking for.
Stef
Le 23/10/16 à 18:35, stepharo a écrit :
|
In reply to this post by kilon.alios
aaaaaand I was wrong, my bad
On Sun, Oct 23, 2016 at 7:29 PM Dimitris Chloupis <[hidden email]> wrote:
|
In reply to this post by stepharo
I usually use 12.222222222222221 round: 2 "12.22".
Peter On Sun, Oct 23, 2016 at 06:38:47PM +0200, stepharo wrote: > 3.1479 roundUpTo: 0.01 is what I was looking for. > > > Stef > > > > Le 23/10/16 à 18:35, stepharo a écrit : > > > >I see. > > > >I writing a little example for my new newbies book > > > >now how can get only two digits after the . > > > > > >Stef > > > > > >Le 23/10/16 à 18:23, Thierry Goubier a écrit : > >>I think that's called 'welcome to the wonderfull world of > >>floating points approximations' and not a bug :( > >> > >>See unums/Gustafson for something more interesting on the subject. > >> > >>Thierry > >> > >>2016-10-23 18:16 GMT+02:00 stepharo <[hidden email] > >><mailto:[hidden email]>>: > >> > >> Hi > >> > >> I'm wondering if we do not have a bug here > >> > >> 12.222222222222221 roundTo: 0.1 > >> "12.200000000000001" > >> > >> 12.222222222222221 roundTo: 0.01 > >> "12.22" > >> > >> > >> Stef > >> > >> > >> > > > |
Thanks because roundUpTo: did not make it either :)
Le 23/10/16 à 18:45, Peter Uhnak a écrit : > I usually use 12.222222222222221 round: 2 "12.22". > > Peter > > On Sun, Oct 23, 2016 at 06:38:47PM +0200, stepharo wrote: >> 3.1479 roundUpTo: 0.01 is what I was looking for. >> >> >> Stef >> >> >> >> Le 23/10/16 à 18:35, stepharo a écrit : >>> I see. >>> >>> I writing a little example for my new newbies book >>> >>> now how can get only two digits after the . >>> >>> >>> Stef >>> >>> >>> Le 23/10/16 à 18:23, Thierry Goubier a écrit : >>>> I think that's called 'welcome to the wonderfull world of >>>> floating points approximations' and not a bug :( >>>> >>>> See unums/Gustafson for something more interesting on the subject. >>>> >>>> Thierry >>>> >>>> 2016-10-23 18:16 GMT+02:00 stepharo <[hidden email] >>>> <mailto:[hidden email]>>: >>>> >>>> Hi >>>> >>>> I'm wondering if we do not have a bug here >>>> >>>> 12.222222222222221 roundTo: 0.1 >>>> "12.200000000000001" >>>> >>>> 12.222222222222221 roundTo: 0.01 >>>> "12.22" >>>> >>>> >>>> Stef >>>> >>>> >>>> > |
In reply to this post by stepharo
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 Printf I am just used to C printf and well, I like the way it works. Phil On Sun, Oct 23, 2016 at 6:35 PM, stepharo <[hidden email]> wrote:
|
+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
signature.asc (859 bytes) Download Attachment |
> On 25 Oct 2016, at 11:05, Henrik Johansen <[hidden email]> wrote: > > +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 YES !! So true. >> On 23 Oct 2016, at 7:08 , [hidden email] 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 |
In reply to this post by Henrik Sperre Johansen
Ok for the advice Now round: aNumberOfDigits seems to work fine. Stef Le 25/10/16 à 11:05, Henrik Johansen a
écrit :
+1. |
2016-10-25 23:22 GMT+02:00 stepharo <[hidden email]>:
No it's not, but issues are timing out too fast ;) https://pharo.fogbugz.com/f/cases/15471/Can-t-round-Float-fmax-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-decimal-places-is-not-in-agreement-with-printShowingDecimalPlaces I hate to say that, but try in python, they got it right...
|
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. 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-26 9:14 GMT+02:00 stepharo <[hidden email]>:
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...
|
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 <[hidden email]> wrote:
|
In reply to this post by Nicolas Cellier
Hi Nicolas,
regarding rounding Fractions: i use fractions if i want to get an exact result (eg for comparing the result with Float calculations). if #round: returns a Float all further calcs (with Fractions) will get contaminated, since the rest will become Floats too. Hence the "asScaledDecimal: numberOfWishedDecimal" seems better to me, but i wonder why these transformations at the end are necessary at all? just for the looks? i'd suppose every person, who knows how to use Fractions, also knows how to append a #asScaledDecimal: to a result by himself, should he want that. taking as an example financial calcs that first use 2 decimals. occasionaly the final result will be basepoints, often small ones like 0.003. with scaledDecimals the result would be (ok, look like) 0 since scaledDecimals also contaminate the calc. of course one could correct this simply with an #asScaledDecimal:3 at the end. nevertheless a first look at the zero result would surprise me for a tenth of a second. werner On 10/26/2016 09:58 AM, Nicolas Cellier wrote:
|
2016-10-26 13:11 GMT+02:00 test <[hidden email]>:
Hi Werner, I don't know the purpose of round: at all. Most often this kind of message was used before printing probably because lack of versatile formatted print messages. In Squeak I replaced most usages of roundTo: by printShowing(Max)DecimalPlaces:. Now if it has been added in Pharo and other languages, there must be some use cases I presume. Maybe the analysis could be carried on these use cases? Beware, converting a Fraction asScaledDecimal will NOT round. Only the printString is rounded, but the number keeps its whole precision. Example (1/3 asScaledDecimal: 1)*3 = 1.0s, not 0.9s. ScaledDecimals as they are now are just Fraction with a different printString... Not very much added value. Nicolas
|
Hi Nicolas,
yes, i know. suppose you calc some financial thing and one intermediate result will be in $. you have to round this Fraction-result to 2 decimals. now you use this to further calc basepoints as the final result. you have to convert this to 3 decimals. looking at this final result with 2 decimals can be be irritating for a moment, if you debug the calcs. and <g> btw i never use scaledDecimals. werner On 10/26/2016 02:06 PM, Nicolas Cellier wrote:
|
Sorry for being slow minded,
yes of course financial apps is exactly the case where round: would be usefull and NEEDS to be exact. 2016-10-26 14:23 GMT+02:00 test <[hidden email]>:
|
Free forum by Nabble | Edit this page |