Le 26/10/16 à 14:52, Nicolas Cellier a écrit :
Sorry for being slow minded,
yes of course financial apps is exactly the case where round: would be usefull and NEEDS to be exact.

so what is the solution?
I'm lost again.

    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:


    2016-10-26 13:11 GMT+02:00 test <wkass...@libello.com
    <mailto:wkass...@libello.com>>:

        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


    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

        On 10/26/2016 09:58 AM, Nicolas Cellier wrote:


        2016-10-26 9:14 GMT+02:00 stepharo <steph...@free.fr
        <mailto: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...





Reply via email to