9

While writing a program I came across finding the cube root of a number in one of my functions.

when I used the below code, I was getting an incorrect value for the cube root (1 was getting printed for n = 64).

public static void cubicPairs(double n)
{
    double root = (System.Math.Pow(n, (1/3)));
    Console.WriteLine(root);
}

Now after I changed the code slightly to this,

public static void cubicPairs(double n)
{
    double root = (System.Math.Pow(n, (1.0/3.0))); //Changed how second parameter is passed
    Console.WriteLine(root);
}

I got root = 3.9999999999999996 (while debugging) but the method was printing 4 (which is correct).

Why is there a difference between the two values and if this has to do with the second parameter to the System.Math.Pow() method (i.e, 1.0/3.0 which is a recursive value), what should I use to find cube root so that I get 4 (while debugging) rather than 3.9999999999999996?

dav_i
  • 27,509
  • 17
  • 104
  • 136
gkb
  • 1,449
  • 2
  • 15
  • 30
  • 3
    I think that in the first case the result of 1/3 is an int, so you ended up doing n^0 – isalgueiro Sep 09 '14 at 11:55
  • @isalgueiro but the parameter has to be a double value and not an int. If it was getting converted to int, shouldn't have I gotten any error or something? – gkb Sep 09 '14 at 11:57
  • 3
    @gopal No because `int` is implicitly convertible to `double`. – dav_i Sep 09 '14 at 11:59
  • @dav_i agreed but should it get implicitly converted to int if 1/3 is not supposed to be an integer as required by the method definition? – gkb Sep 09 '14 at 12:02
  • 2
    (1/3) *is* an integer, whatever it is supposed to be. The runtime is able to convert it to what you want, so does it. – Patrice Gahide Sep 09 '14 at 12:03
  • (1/3) = 0, (1.0/3.0) = 0.33333... You do need to put these value in double first so the division result return double instead of int. – Franck Sep 09 '14 at 12:05

5 Answers5

18

This is a standard trap in the { curly brace languages }, C# included, a division with integral operands is performed as an integer division, not a floating point division. It always yields an integer result, 1 / 3 produces 0. Raising any number to the power of 0 produces 1.0

You force a floating point division by converting one of the operands to double. Like 1.0 / 3 or (double)integerVariable / 3.

Similar problem with multiplication, but usually less of a trap, integral operands produce an integral result that risks overflow. This otherwise reflects the way the processor works, it has distinct instructions for these operations, IMUL vs FMUL and IDIV vs FDIV. The latter one being rather famous for a bug in the Pentium processor :)

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
1

You can try running this code for cube root functionality.

textBox2.Text = Math.Pow(Convert.ToDouble(textBox1.Text), 0.3333333333333333).ToString();
CubeJockey
  • 2,209
  • 8
  • 24
  • 31
Nitin Gaur
  • 19
  • 1
-1

The error (which, by the way, is just 4E-16 - 400 quintillionths) is caused by floating point errors.

You could circumvent this by rounding the number if it is within a certain threshold:

public static void cubicPairs(double n)
{
    double root = (System.Math.Pow(n, (1/3)));
    double roundedRoot = Math.Round(root);

    if (Math.Abs(roundedRoot - root) < VERY_SMALL_NUMBER)
        return roundedRoot;
    else
        return root;
}

Where VERY_SMALL_NUMBER can be, say, 1e-10.

Sean Latham
  • 250
  • 1
  • 12
  • double root = (System.Math.Pow(n, (1.0/3.0))); yields better result by treating result of 1/3 as floating point. – Mike Meinz Nov 28 '14 at 14:29
-1
public static void Main()
{
    int a= int.Parse(Console.ReadLine());
    int sum=0;

    for(int i=0 ; i<= a ;i++)
    {
        for(int j=0 ; j<i ;j++)
        {
            sum =+ (i*i);
        }
        Console.WriteLine("Number is : {0} and cube of the {0} is :{1} \n",i,sum*i);
    }
}
seyed
  • 1
  • 3
-2

Try it

Math.Ceiling(Math.Pow(n, (double)1 / 3));
Zoe
  • 27,060
  • 21
  • 118
  • 148
  • this only works if the OP wants integer results, and if `Math.Pow(n, (double)1 / 3)` returns a result slightly smaller than the real value. If it returns 4.0000000001 for example then your solution is completely wrong – phuclv Oct 29 '19 at 14:45