Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Excel's MOD in C#?

Excel's MOD in C#?

Scheduled Pinned Locked Moved C#
questioncsharpcom
16 Posts 6 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    Jassim Rahma
    wrote on last edited by
    #1

    How can I do this Excel's MOD formula in C#:

    =MOD(-1.779406909, 2 * PI())

    Thanks, Jassim

    www.softnames.com

    P B 2 Replies Last reply
    0
    • J Jassim Rahma

      How can I do this Excel's MOD formula in C#:

      =MOD(-1.779406909, 2 * PI())

      Thanks, Jassim

      www.softnames.com

      P Offline
      P Offline
      Pete OHanlon
      wrote on last edited by
      #2

      You put % between the numbers.

      Advanced TypeScript Programming Projects

      J 1 Reply Last reply
      0
      • P Pete OHanlon

        You put % between the numbers.

        Advanced TypeScript Programming Projects

        J Offline
        J Offline
        Jassim Rahma
        wrote on last edited by
        #3

        I tried that.. Excel returns 4.503778398 This is the figure I am trying to achieve But... double bearing4 = Math.Floor(-1.7794 / (2 * Math.PI)); returns -1 and this: double bearing4 = -1.779406909 % (2 * Math.PI); returns: -1.779406909

        www.softnames.com

        P OriginalGriffO 2 Replies Last reply
        0
        • J Jassim Rahma

          I tried that.. Excel returns 4.503778398 This is the figure I am trying to achieve But... double bearing4 = Math.Floor(-1.7794 / (2 * Math.PI)); returns -1 and this: double bearing4 = -1.779406909 % (2 * Math.PI); returns: -1.779406909

          www.softnames.com

          P Offline
          P Offline
          Peter_in_2780
          wrote on last edited by
          #4

          Modulo and negative numbers make an explosive mix. See the last table in Modulo operation - Wikipedia[^]. One common trick is to do something like

          result = (a + n*b) % b

          where n is some "sufficiently large" integer. Cheers, Peter

          Software rusts. Simon Stephenson, ca 1994. So does this signature. me, 2012

          J 1 Reply Last reply
          0
          • J Jassim Rahma

            I tried that.. Excel returns 4.503778398 This is the figure I am trying to achieve But... double bearing4 = Math.Floor(-1.7794 / (2 * Math.PI)); returns -1 and this: double bearing4 = -1.779406909 % (2 * Math.PI); returns: -1.779406909

            www.softnames.com

            OriginalGriffO Offline
            OriginalGriffO Offline
            OriginalGriff
            wrote on last edited by
            #5

            MOD in Excel is a true Modulus: % in C# is a remainder, and the two are not the same: Mod and Remainder are not the Same – Rob Conery[^] What you need is to write a modulus method:

                private double Mod(double a, double b)
                    {
                    return a - b \* Math.Floor(a / b);
                    }
            

            Call that, and you'll get the answer you're expecting.

            Sent from my Amstrad PC 1640 Never throw anything away, Griff Bad command or file name. Bad, bad command! Sit! Stay! Staaaay... AntiTwitter: @DalekDave is now a follower!

            "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
            "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt

            J B 2 Replies Last reply
            0
            • P Peter_in_2780

              Modulo and negative numbers make an explosive mix. See the last table in Modulo operation - Wikipedia[^]. One common trick is to do something like

              result = (a + n*b) % b

              where n is some "sufficiently large" integer. Cheers, Peter

              Software rusts. Simon Stephenson, ca 1994. So does this signature. me, 2012

              J Offline
              J Offline
              Jassim Rahma
              wrote on last edited by
              #6

              double bearing4 = (-1.779406909 + 2 * Math.PI) % Math.PI;

              It returns 1.362 which is different that Excel

              www.softnames.com

              P 1 Reply Last reply
              0
              • OriginalGriffO OriginalGriff

                MOD in Excel is a true Modulus: % in C# is a remainder, and the two are not the same: Mod and Remainder are not the Same – Rob Conery[^] What you need is to write a modulus method:

                    private double Mod(double a, double b)
                        {
                        return a - b \* Math.Floor(a / b);
                        }
                

                Call that, and you'll get the answer you're expecting.

                Sent from my Amstrad PC 1640 Never throw anything away, Griff Bad command or file name. Bad, bad command! Sit! Stay! Staaaay... AntiTwitter: @DalekDave is now a follower!

                J Offline
                J Offline
                Jassim Rahma
                wrote on last edited by
                #7

                Yes Yes Yes Thank you so much

                www.softnames.com

                OriginalGriffO 1 Reply Last reply
                0
                • J Jassim Rahma

                  double bearing4 = (-1.779406909 + 2 * Math.PI) % Math.PI;

                  It returns 1.362 which is different that Excel

                  www.softnames.com

                  P Offline
                  P Offline
                  Peter_in_2780
                  wrote on last edited by
                  #8

                  Jassim Rahma wrote:

                  which is different that Excel

                  which is because you're calculating something different.

                  Software rusts. Simon Stephenson, ca 1994. So does this signature. me, 2012

                  1 Reply Last reply
                  0
                  • J Jassim Rahma

                    Yes Yes Yes Thank you so much

                    www.softnames.com

                    OriginalGriffO Offline
                    OriginalGriffO Offline
                    OriginalGriff
                    wrote on last edited by
                    #9

                    You're welcome!

                    Sent from my Amstrad PC 1640 Never throw anything away, Griff Bad command or file name. Bad, bad command! Sit! Stay! Staaaay... AntiTwitter: @DalekDave is now a follower!

                    "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
                    "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt

                    1 Reply Last reply
                    0
                    • OriginalGriffO OriginalGriff

                      MOD in Excel is a true Modulus: % in C# is a remainder, and the two are not the same: Mod and Remainder are not the Same – Rob Conery[^] What you need is to write a modulus method:

                          private double Mod(double a, double b)
                              {
                              return a - b \* Math.Floor(a / b);
                              }
                      

                      Call that, and you'll get the answer you're expecting.

                      Sent from my Amstrad PC 1640 Never throw anything away, Griff Bad command or file name. Bad, bad command! Sit! Stay! Staaaay... AntiTwitter: @DalekDave is now a follower!

                      B Offline
                      B Offline
                      BillWoodruff
                      wrote on last edited by
                      #10

                      Also useful background: Eric Lippert "What’s the difference? Remainder vs Modulus" [^]

                      «Where is the Life we have lost in living? Where is the wisdom we have lost in knowledge? Where is the knowledge we have lost in information?» T. S. Elliot

                      1 Reply Last reply
                      0
                      • J Jassim Rahma

                        How can I do this Excel's MOD formula in C#:

                        =MOD(-1.779406909, 2 * PI())

                        Thanks, Jassim

                        www.softnames.com

                        B Offline
                        B Offline
                        BillWoodruff
                        wrote on last edited by
                        #11

                        what I use:

                        using System;
                        using System.Runtime.InteropServices.WindowsRuntime;

                        namespace Utilities
                        {
                        public static class MathExtensions
                        {
                        // ideas from: Lippert, Gravell, Skeet
                        public static double ModT(this T i1, T i2)
                        {
                        double v1 = i1.GetDouble();
                        double v2 = i2.GetDouble();
                        return v1 - v2 * Math.Floor(v1 / v2);
                        }

                            public static double ModT1T2(this T1 i1, T2 i2)
                            {
                                double v1 = i1.GetDouble();
                                double v2 = i2.GetDouble();
                                return v1 - v2 \* Math.Floor(v1 / v2);
                            }
                        
                            public static double GetDouble(this T i1)
                            {
                                double v1;
                        
                                try
                                {
                                    v1 = Convert.ToDouble(i1);
                                }
                                catch (InvalidCastException iex)
                                {
                                    throw new InvalidCastException($"type {typeof(T)} cannot be cast to double: {iex.Message}");
                                }
                        
                                catch (FormatException fex)
                                {
                                    throw new FormatException($"type {typeof(T)} cannot be used: {fex.Message}");
                                }
                        
                                catch (OverflowException oex)
                                {
                                    throw new OverflowException($"type {typeof(T)} result is an overflow: {oex.Message}");
                                }
                        
                                return v1;
                            }
                        }
                        

                        }

                        Tests:

                                double dbl = -1.779406909.ModT(2 \* Math.PI);
                        
                                double int1 = 221.ModT(20);
                        
                                double sngl = 102.0f.ModT(20.0f);
                        
                                double deci = 102.0m.ModT(20.0m);
                        
                                double intdecicombo = 100.0.ModT1T2(34.56m);
                        
                                double dbl2 = 100.0.ModT(34.56);
                        

                        «Where is the Life we have lost in living? Where is the wisdom we have lost in knowledge? Where is the knowledge we have lost in information?» T. S. Elliot

                        Richard DeemingR 1 Reply Last reply
                        0
                        • B BillWoodruff

                          what I use:

                          using System;
                          using System.Runtime.InteropServices.WindowsRuntime;

                          namespace Utilities
                          {
                          public static class MathExtensions
                          {
                          // ideas from: Lippert, Gravell, Skeet
                          public static double ModT(this T i1, T i2)
                          {
                          double v1 = i1.GetDouble();
                          double v2 = i2.GetDouble();
                          return v1 - v2 * Math.Floor(v1 / v2);
                          }

                              public static double ModT1T2(this T1 i1, T2 i2)
                              {
                                  double v1 = i1.GetDouble();
                                  double v2 = i2.GetDouble();
                                  return v1 - v2 \* Math.Floor(v1 / v2);
                              }
                          
                              public static double GetDouble(this T i1)
                              {
                                  double v1;
                          
                                  try
                                  {
                                      v1 = Convert.ToDouble(i1);
                                  }
                                  catch (InvalidCastException iex)
                                  {
                                      throw new InvalidCastException($"type {typeof(T)} cannot be cast to double: {iex.Message}");
                                  }
                          
                                  catch (FormatException fex)
                                  {
                                      throw new FormatException($"type {typeof(T)} cannot be used: {fex.Message}");
                                  }
                          
                                  catch (OverflowException oex)
                                  {
                                      throw new OverflowException($"type {typeof(T)} result is an overflow: {oex.Message}");
                                  }
                          
                                  return v1;
                              }
                          }
                          

                          }

                          Tests:

                                  double dbl = -1.779406909.ModT(2 \* Math.PI);
                          
                                  double int1 = 221.ModT(20);
                          
                                  double sngl = 102.0f.ModT(20.0f);
                          
                                  double deci = 102.0m.ModT(20.0m);
                          
                                  double intdecicombo = 100.0.ModT1T2(34.56m);
                          
                                  double dbl2 = 100.0.ModT(34.56);
                          

                          «Where is the Life we have lost in living? Where is the wisdom we have lost in knowledge? Where is the knowledge we have lost in information?» T. S. Elliot

                          Richard DeemingR Offline
                          Richard DeemingR Offline
                          Richard Deeming
                          wrote on last edited by
                          #12

                          BillWoodruff wrote:

                          catch (InvalidCastException iex)
                          {
                          throw new InvalidCastException($"type {typeof(T)} cannot be cast to double: {iex.Message}");
                          }

                          If you're going to wrap an exception, you should pass the wrapped exception as the inner exception. You should probably review the error messages as well. For example, it might be fine to use the given type, but not the specified value.

                          catch (InvalidCastException iex)
                          {
                          throw new InvalidCastException($"Type {typeof(T)} cannot be cast to double: {iex.Message}", iex);
                          }
                          catch (FormatException fex)
                          {
                          throw new FormatException($"Value '{i1}' of type {typeof(T)} cannot be converted to a double: {fex.Message}", fex);
                          }
                          catch (OverflowException oex)
                          {
                          throw new OverflowException($"Value '{i1}' of type {typeof(T)} is too large for a double: {oex.Message}", oex);
                          }

                          You can also eliminate the InvalidCastException by adding a generic type constraint, since the documentation[^] says it's only thrown if the value to convert doesn't implement IConvertible:

                          public static double ModT<T>(this T i1, T i2) where T : IConvertible { ... }
                          public static double ModT1T2<T1, T2>(this T1 i1, T2 i2) where T1 : IConvertible where T2 : IConvertible { ... }
                          public static double GetDouble<T>(this T i1) where T : IConvertible { ... }


                          "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

                          "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

                          B 1 Reply Last reply
                          0
                          • Richard DeemingR Richard Deeming

                            BillWoodruff wrote:

                            catch (InvalidCastException iex)
                            {
                            throw new InvalidCastException($"type {typeof(T)} cannot be cast to double: {iex.Message}");
                            }

                            If you're going to wrap an exception, you should pass the wrapped exception as the inner exception. You should probably review the error messages as well. For example, it might be fine to use the given type, but not the specified value.

                            catch (InvalidCastException iex)
                            {
                            throw new InvalidCastException($"Type {typeof(T)} cannot be cast to double: {iex.Message}", iex);
                            }
                            catch (FormatException fex)
                            {
                            throw new FormatException($"Value '{i1}' of type {typeof(T)} cannot be converted to a double: {fex.Message}", fex);
                            }
                            catch (OverflowException oex)
                            {
                            throw new OverflowException($"Value '{i1}' of type {typeof(T)} is too large for a double: {oex.Message}", oex);
                            }

                            You can also eliminate the InvalidCastException by adding a generic type constraint, since the documentation[^] says it's only thrown if the value to convert doesn't implement IConvertible:

                            public static double ModT<T>(this T i1, T i2) where T : IConvertible { ... }
                            public static double ModT1T2<T1, T2>(this T1 i1, T2 i2) where T1 : IConvertible where T2 : IConvertible { ... }
                            public static double GetDouble<T>(this T i1) where T : IConvertible { ... }


                            "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

                            B Offline
                            B Offline
                            BillWoodruff
                            wrote on last edited by
                            #13

                            Well, there is no code I write you cannot improve, and I am happy to see the improvements, no matter how ephemeral :) You are already aware, I'm sure, of the long-standing issue in constraining generic parameters to numeric Types. If you're going to constrain, might as well go for broke:

                             where T:
                                  struct, 
                                  IComparable, 
                                  IComparable, 
                                  IConvertible, 
                                  IEquatable, 
                                  IFormattable
                            

                            Note: var c1dbl = 'z'.ModT('a'); // invalid cast error Of course, that's somewhat ironic :) since you can do this: int c1int = 'z' % 'a'; // returns #25

                            «Where is the Life we have lost in living? Where is the wisdom we have lost in knowledge? Where is the knowledge we have lost in information?» T. S. Elliot

                            Richard DeemingR 1 Reply Last reply
                            0
                            • B BillWoodruff

                              Well, there is no code I write you cannot improve, and I am happy to see the improvements, no matter how ephemeral :) You are already aware, I'm sure, of the long-standing issue in constraining generic parameters to numeric Types. If you're going to constrain, might as well go for broke:

                               where T:
                                    struct, 
                                    IComparable, 
                                    IComparable, 
                                    IConvertible, 
                                    IEquatable, 
                                    IFormattable
                              

                              Note: var c1dbl = 'z'.ModT('a'); // invalid cast error Of course, that's somewhat ironic :) since you can do this: int c1int = 'z' % 'a'; // returns #25

                              «Where is the Life we have lost in living? Where is the wisdom we have lost in knowledge? Where is the knowledge we have lost in information?» T. S. Elliot

                              Richard DeemingR Offline
                              Richard DeemingR Offline
                              Richard Deeming
                              wrote on last edited by
                              #14

                              That's an annoying restriction on the char type. All of the floating-point IConvertible members throw an InvalidCastException. But casting to a floating-point type, either explicitly or implicitly, works. :doh:

                              char c = '*';
                              double a = (double)c; // Works
                              double b = Convert.ToDouble(c); // Throws

                              Reference Source[^]


                              "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

                              "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

                              B 1 Reply Last reply
                              0
                              • Richard DeemingR Richard Deeming

                                That's an annoying restriction on the char type. All of the floating-point IConvertible members throw an InvalidCastException. But casting to a floating-point type, either explicitly or implicitly, works. :doh:

                                char c = '*';
                                double a = (double)c; // Works
                                double b = Convert.ToDouble(c); // Throws

                                Reference Source[^]


                                "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

                                B Offline
                                B Offline
                                BillWoodruff
                                wrote on last edited by
                                #15

                                Would it be the language we love without these quirks :omg: Seems to me we could have had INumericType ... IIntType ... IFloatType constraints ... by now ... given the frequency of posts about the necessity for these. cheers, Bill

                                «Where is the Life we have lost in living? Where is the wisdom we have lost in knowledge? Where is the knowledge we have lost in information?» T. S. Elliot

                                Richard DeemingR 1 Reply Last reply
                                0
                                • B BillWoodruff

                                  Would it be the language we love without these quirks :omg: Seems to me we could have had INumericType ... IIntType ... IFloatType constraints ... by now ... given the frequency of posts about the necessity for these. cheers, Bill

                                  «Where is the Life we have lost in living? Where is the wisdom we have lost in knowledge? Where is the knowledge we have lost in information?» T. S. Elliot

                                  Richard DeemingR Offline
                                  Richard DeemingR Offline
                                  Richard Deeming
                                  wrote on last edited by
                                  #16

                                  Looks like it's part of a much larger discussion that's going to take a while to make it into the language (if it ever does): Champion "Type Classes (aka Concepts, Structural Generic Constraints)" · Issue #110 · dotnet/csharplang · GitHub[^] Meanwhile, you can "fake" it by using Jon Skeet's generic operators from the MiscUtil project: Generic Operators[^] It hasn't been updated since 2009, but the concept still works. For example:

                                  using System.Linq.Expressions;

                                  public static class GenericOperators<T>
                                  {
                                  public static readonly Func<T, T, T> Add = Create(Expression.Add);
                                  public static readonly Func<T, T, T> Subtract = Create(Expression.Subtract);
                                  public static readonly Func<T, T, T> Multiply = Create(Expression.Multiply);
                                  public static readonly Func<T, T, T> Divide = Create(Expression.Divide);

                                  private static Func<T, T, T> Create(Func<Expression, Expression, BinaryExpression> body)
                                  {
                                      try
                                      {
                                          Type typeT = typeof(T);
                                          var left = Expression.Parameter(typeT, "left");
                                          var right = Expression.Parameter(typeT, "right");
                                  
                                          if (typeT.IsEnum)
                                          {
                                              Type enumType = Enum.GetUnderlyingType(typeT);
                                              var x = Expression.Convert(left, enumType);
                                              var y = Expression.Convert(right, enumType);
                                  
                                              Expression op = body(x, y);
                                              if (op.Type == enumType) op = Expression.Convert(op, typeT);
                                  
                                              return Expression.Lambda<Func<T, T, T>>(op, left, right).Compile();
                                          }
                                  
                                          return Expression.Lambda<Func<T, T, T>>(body(left, right), left, right).Compile();
                                      }
                                      catch (InvalidOperationException ex)
                                      {
                                          string message = ex.Message;
                                          return delegate { throw new InvalidOperationException(message); };
                                      }
                                      catch (ArgumentException ex)
                                      {
                                          string message = ex.Message;
                                          return delegate { throw new InvalidOperationException(message); };
                                      }
                                  }
                                  

                                  }

                                  Of course, it wouldn't help much in this case, because you'd still n

                                  "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

                                  1 Reply Last reply
                                  0
                                  Reply
                                  • Reply as topic
                                  Log in to reply
                                  • Oldest to Newest
                                  • Newest to Oldest
                                  • Most Votes


                                  • Login

                                  • Don't have an account? Register

                                  • Login or register to search.
                                  • First post
                                    Last post
                                  0
                                  • Categories
                                  • Recent
                                  • Tags
                                  • Popular
                                  • World
                                  • Users
                                  • Groups