Custom decimal round

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • =?Utf-8?B?THVpZ2k=?=

    Custom decimal round

    Hi all,
    I need to round a decimal value with a particular rule.
    For example:

    decimal a = 1.49m -1m
    decimal a = 1.5m -1m
    decimal a = 1.51m -2m

    I've tried Math.Round but with the value 1.5 it returns me 2, which it is
    not correct for my business rule.

    How can I solve this problem?

    Thanks in advance.


    --
    Luigi

  • Jon Skeet [C# MVP]

    #2
    Re: Custom decimal round

    On Jul 1, 3:23 pm, Luigi <ciupazNoSpamGr a...@inwind.itw rote:
    I need to round a decimal value with a particular rule.
    For example:
    >
    decimal a = 1.49m -1m
    decimal a = 1.5m -1m
    decimal a = 1.51m -2m
    >
    I've tried Math.Round but with the value 1.5 it returns me 2, which it is
    not correct for my business rule.
    >
    How can I solve this problem?
    I'd write a custom rounding method. It's reasonable simple if you have
    a very specific requirement. In this case, something like:

    public decimal Round (decimal value)
    {
    decimal floor = Math.Floor(valu e);
    decimal ceiling = Math.Floor(valu e);
    decimal midpoint = (floor+ceiling)/2;
    return value <= midpoint ? floor : ceiling;
    }

    It's possible that there will be some weird problems around the very
    largest numbers that decimals can store, but if your application
    doesn't use those (and it's unlikely to) then you should be okay.

    This is completely untested though - I strongly recommend writing unit
    tests for it!

    Jon

    Comment

    • Marc Gravell

      #3
      Re: Custom decimal round

      How about something cheeky like:

      decimal a = Math.Ceiling(x-0.5M);

      Obviously you'd need to think about -ves etc...

      Marc

      Comment

      • SLL

        #4
        Re: Custom decimal round

        On Jul 1, 10:23 am, Luigi <ciupazNoSpamGr a...@inwind.itw rote:
        Hi all,
        I need to round a decimal value with a particular rule.
        For example:
        >
        decimal a = 1.49m -1m
        decimal a = 1.5m -1m
        decimal a = 1.51m -2m
        >
        I've tried Math.Round but with the value 1.5 it returns me 2, which it is
        not correct for my business rule.
        >
        How can I solve this problem?
        >
        Thanks in advance.
        >
        --
        Luigi
        Try multiplying by 10*(number of decimals needed), used math.floor or
        math.ceiling, then divide by same number 10*(number of decimals
        needed)

        Comment

        • Marc Gravell

          #5
          Re: Custom decimal round


          Assuming you mean 10 raised-to-the-power-of (number of decimals), the OP
          appears to want zero decimals. Taking the cited example 1.51, this would
          give 1M, not 2M as desired.

          Marc

          Comment

          • rossum

            #6
            Re: Custom decimal round

            On Tue, 1 Jul 2008 07:55:38 -0700 (PDT), "Jon Skeet [C# MVP]"
            <skeet@pobox.co mwrote:
            >On Jul 1, 3:23 pm, Luigi <ciupazNoSpamGr a...@inwind.itw rote:
            >I need to round a decimal value with a particular rule.
            >For example:
            >>
            >decimal a = 1.49m -1m
            >decimal a = 1.5m -1m
            >decimal a = 1.51m -2m
            >>
            >I've tried Math.Round but with the value 1.5 it returns me 2, which it is
            >not correct for my business rule.
            >>
            >How can I solve this problem?
            >
            >I'd write a custom rounding method. It's reasonable simple if you have
            >a very specific requirement. In this case, something like:
            >
            >public decimal Round (decimal value)
            >{
            decimal floor = Math.Floor(valu e);
            decimal ceiling = Math.Floor(valu e);
            Did you mean "decimal ceiling = Math.Ceiling(va lue);"? rossum
            decimal midpoint = (floor+ceiling)/2;
            return value <= midpoint ? floor : ceiling;
            >}
            >
            >It's possible that there will be some weird problems around the very
            >largest numbers that decimals can store, but if your application
            >doesn't use those (and it's unlikely to) then you should be okay.
            >
            >This is completely untested though - I strongly recommend writing unit
            >tests for it!
            >
            >Jon

            Comment

            • Jon Skeet [C# MVP]

              #7
              Re: Custom decimal round

              rossum <rossum48@coldm ail.comwrote:

              <snip>
              decimal ceiling = Math.Floor(valu e);
              Did you mean "decimal ceiling = Math.Ceiling(va lue);"? rossum
              Yup. That's what I get for not testing it...

              --
              Jon Skeet - <skeet@pobox.co m>
              Web site: http://www.pobox.com/~skeet
              Blog: http://www.msmvps.com/jon_skeet
              C# in Depth: http://csharpindepth.com

              Comment

              • =?Utf-8?B?THVpZ2k=?=

                #8
                Re: Custom decimal round

                Thank you all very much.
                I'll try this one method:

                decimal x = 1.51m;

                decimal a = Math.Ceiling(x - 0.5M);

                Luigi

                Comment

                • Marc Gravell

                  #9
                  Re: Custom decimal round

                  Note that this is called the banker rounding

                  I'm fairly certain that the original question as posed doesn't relate
                  to banker's rounding; it is just .5 always rounding down.

                  Marc

                  Comment

                  • Michel Walsh

                    #10
                    Re: Custom decimal round

                    Yes, sorry, I was not clear. The OP want a rounding down at 0.5, but GOT a
                    banker rounding, with Math.Round(x, 0).

                    Vanderghast, Access MVP


                    "Marc Gravell" <marc.gravell@g mail.comwrote in message
                    news:c1e60763-827e-44a7-9cfc-22a65367e3cf@56 g2000hsm.google groups.com...
                    >Note that this is called the banker rounding
                    >
                    I'm fairly certain that the original question as posed doesn't relate
                    to banker's rounding; it is just .5 always rounding down.
                    >
                    Marc

                    Comment

                    • =?Utf-8?B?THVpZ2k=?=

                      #11
                      Re: Custom decimal round

                      Another question.
                      To adhere to these rules when the values are negative:

                      Criteria to round negative amounts are the following:
                      -1.5 =- 1
                      - 1.6 =- 2
                      -1.4 =- 1


                      how can I write a method that make this rounding?
                      Values are decimal.

                      Thanks.

                      Luigi

                      Comment

                      • Marc Gravell

                        #12
                        Re: Custom decimal round

                        If this follows the same rules as +ve, but negated - then perhaps just
                        check whether the value is <0, and then:
                        * negate the value (making it +ve)
                        * apply the current rounding logic (which works for +ve)
                        * negate the result (making it -ve)

                        Marc

                        Comment

                        • =?Utf-8?B?THVpZ2k=?=

                          #13
                          Re: Custom decimal round

                          "Marc Gravell" wrote:
                          If this follows the same rules as +ve, but negated - then perhaps just
                          check whether the value is <0, and then:
                          * negate the value (making it +ve)
                          * apply the current rounding logic (which works for +ve)
                          * negate the result (making it -ve)
                          >
                          I'm using:

                          decimal a = Math.Ceiling(x-0.5M);

                          but not works correctly.

                          -1.6 --1 (and not -2)

                          L

                          Comment

                          • Michel Walsh

                            #14
                            Re: Custom decimal round

                            The ceiling is the first integer greater or equal to its argument.
                            Technically, -1 is greater than (is to the 'right' of, if you draw the x
                            axis) -1.6. -2 is smaller, and to the left, of -1,.6.

                            As suggested by Marc Gravel, you can use:



                            y = ( x>=0) ? roundingPositiv eValue(x) : - roundingPositiv eValue( -x )
                            ;



                            where 'roudingPositiv eValue' is your required method.



                            Vanderghast, Access MVP



                            "Luigi" <ciupazNoSpamGr azie@inwind.itw rote in message
                            news:F9FB07BE-02F9-4F07-9ADD-2002F5E7C31E@mi crosoft.com...
                            "Marc Gravell" wrote:
                            >
                            >If this follows the same rules as +ve, but negated - then perhaps just
                            >check whether the value is <0, and then:
                            >* negate the value (making it +ve)
                            >* apply the current rounding logic (which works for +ve)
                            >* negate the result (making it -ve)
                            >>
                            I'm using:
                            >
                            decimal a = Math.Ceiling(x-0.5M);
                            >
                            but not works correctly.
                            >
                            -1.6 --1 (and not -2)
                            >
                            L

                            Comment

                            Working...