-2

I'm relatively new to programming in C#. I'm building an exponent calculator, and I got it working, but while debugging I came across an issue that I do not understand why I get the output that I get.

This is the class and method in question when I get the output I know is wrong. (note i did later fix it by making it total *= lower in the for loop)

using System;

namespace stars
{

  public class Exponent
  {

    public int Exp(int lower, int power)
    {
      int total = lower;
      if ( power == 0 )
      {
        //returns 1 for any exponent of 0
        Console.WriteLine(" 1");
        return 1;
      }
      else if ( lower == 0 )
      {
        //returns 0 for any base of 0
        Console.WriteLine("0");
        return 0;
      }
      else if ( ( power % 1 ) == 0 ) // check for integer exponent
      {
        for ( int i = 1; !( i > power ); i++ )  //math
        {
          lower *= lower;
        }
        Console.WriteLine(lower);
        return total;
      }
      else
      {
        Console.WriteLine("error");
      }
    }

  }

}

at the last elseif, where I have my forloop, to (incorrectly) calculate the value of some integer to the power of another integer, I (incorrectly) perform the calculation lower = lower * lower, where lower is the base number.

i.e. 5^4,, 5 = lower, 4 = power

anyways, when I run it at 5^4, the result is 0. Why does it come out to 0? I figured it would work like this

5 * 5 = 25 ---> 25 * 25 = 625 ----> 625 * 625... etc

or is the end value so large that the compiler spits out 0.

Vivek Nuna
  • 25,472
  • 25
  • 109
  • 197
ajdawg
  • 17
  • 1
  • 1
    The max value for an int in C# is 2,147,483,647. 5^4 is 625, which is a lot smaller that almost 2.147 billion. Also unless you're trying this as an exercise or are wanting to reinvent the wheel use [Math.Pow](https://learn.microsoft.com/en-us/dotnet/api/system.math.pow?view=netframework-4.8) – MindSwipe Oct 11 '19 at 08:49
  • 2
    You don't change `total` – Dmitry Bychenko Oct 11 '19 at 08:59
  • As an addendum to my original comment: Also, if the number were too large for an int it would overflow unless within a a [checked { ... }](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/checked) block or the compiler can be sure at compile time that the integer will overflow (doing `int x = int.MaxValue + 1` triggers this for example) – MindSwipe Oct 11 '19 at 09:14

3 Answers3

1

There are lot of issues in the code, I have fixed them. Though you have to consider other scenarios also. like if lowerand power are negative numbers, if numbers are big, it will not give you the required result.

public static int Exp(int lower, int power) 
{
    int total = lower;
    if (power == 0) {
        //returns 1 for any exponent of 0
        Console.WriteLine(" 1");
        return 1;
    }
    else if (lower == 0) 
    {
        //returns 0 for any base of 0
        Console.WriteLine("0");
        return 0;
    }

    for (int i = 1; i < power; i++) //math
    {
        total *= lower;
    }

    Console.WriteLine(total);
    return total;
}
MindSwipe
  • 7,193
  • 24
  • 47
Vivek Nuna
  • 25,472
  • 25
  • 109
  • 197
1

First of all you should modify total in your routine and don't modify lower changing given parameter is often leads to errors.

Something like this:

public class Exponent 
{
    // static: we don't want this
    public static int Exp(int lower, int power)
    {
        // Special cases  
        if (power == 0 || lower == 1)
            return 1;
        else if (lower == 0)
            return 0;
        else if (power < 0) //DONE: you've forgot about this case
            throw new ArgumentOutOfRangeException(nameof(power));  

        // we don't want "power % 1 == 0" case - int power is always integer

        // General case: math 
        int total = lower;

        // "!( i > power )" - let's put at simpler (and correct) - "i < power" 
        for (int i = 1; i < power; ++i)      
            total *= lower; 

        return total;  
    }
}

...

// 5**4 == 625
Console.Write(Exponent.Exp(5, 4));
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
  • +1 Good catch with the `power < 0`. But you could remove the `else` from the `else if` clauses as you're returning from within the if anyways – MindSwipe Oct 11 '19 at 09:10
0

There's quite a bit wrong styling wise with the code, and there's obviously an error somewhere or else you'd get the correct output. Let's break it down.

First I'll rewrite your code to be cleaner and easier to read:

public int Exp(int lower, int power)
{
    int total = lower;

    // 0 to the power of y is always 0
    if ( lower == 0 )
        return 0;

    // x to the power of 0 is always 1
    if ( power == 0 )
        return 1;

    // Your parameters for the Method explicitly state that 
    // 'power' is always an int, so no need to check
    for ( int i = 1; i < power; i++ )
        lower *= lower;

    return total;
}

The cleanups I did:

  • Removed unnecessary 'else if's from code, as you are returning from within your 'if' anyways
  • Removed unnecessary braces reducing clutter
  • Moved comments to before check, as it is customary to comment code above it not below it

Now the problem is a lot more obvious: You're doing lower *= lower instead of total *= lower. So correct code would be this:

public int Exp(int lower, int power)
{
    int total = lower;

    // 0 to the power of y is always 0
    if ( lower == 0 )
        return 0;

    // x to the power of 0 is always 1
    if ( power == 0 )
        return 1;

    // Your parameters for the Method explicitly state that 
    // 'power' is always an int, so no need to check
    for ( int i = 1; i < power; i++ )
        total *= lower;

    return total;
}
MindSwipe
  • 7,193
  • 24
  • 47