7

Solving one bug I came to some interesting discoveries.

The result of this procedure

    static void Main(string[] args)
    {
        int i4 = 4;
        Console.WriteLine("int i4 = 4;");
        Console.WriteLine("i4 % 1 = {0}", i4 % 1);

        double d4 = 4.0;
        Console.WriteLine("double d4 = 4.0;");
        Console.WriteLine("d4 % 1 = {0}", d4 % 1);
        Console.WriteLine("-----------------------------------------------------------");
        int i64 = 64;
        double dCubeRootOf64 = Math.Pow(i64, 1.0 / 3.0);
        Console.WriteLine("int i64 = 64;");
        Console.WriteLine("double dCubeRootOf64 = Math.Pow(i64, 1.0 / 3.0) = {0}", dCubeRootOf64);
        Console.WriteLine("dCubeRootOf64 = {0}", dCubeRootOf64);
        Console.WriteLine("dCubeRootOf64 % 1 = {0} ??????????????  Why 1. ??????????", dCubeRootOf64 % 1);

        Console.ReadLine();
    }

is

int i4 = 4;
i4 % 1 = 0
double d4 = 4.0;
d4 % 1 = 0
-----------------------------------------------------------
int i64 = 64;
double dCubeRootOf64 = Math.Pow(i64, 1.0 / 3.0) = 4
dCubeRootOf64 = 4
dCubeRootOf64 % 1 = 1 ??????????????  Why 1. ??????????

int 4 % 1 = 0 -- correct

double 4.0 % 1 = 0 -- correct

But bug is in:

Math.Pow(64, 1.0 / 3.0) % 1 = 1

Cube root from 64 is 4. Why is in that case 4 % 1 = 1?

ChrisWue
  • 18,612
  • 4
  • 58
  • 83
SelvirK
  • 925
  • 3
  • 18
  • 42
  • Check out Google: (64^(1/3)) mod 1 – SQLMason May 24 '12 at 19:06
  • If you want to make sure that it's an integer that you're getting the modulo for, try to cast it. – SQLMason May 24 '12 at 19:10
  • You are looking for this I think http://stackoverflow.com/questions/618535/what-is-the-difference-between-decimal-float-and-double-in-c – Nevyn May 24 '12 at 19:11
  • possible duplicate of [Why is modulus operator not working for double in c#?](http://stackoverflow.com/questions/906564/why-is-modulus-operator-not-working-for-double-in-c) – Ian Mercer May 24 '12 at 19:11
  • @IanMercer: No, that's not a duplicate – SLaks May 24 '12 at 19:16
  • 2
    `Math.Pow(x, 1.0 / 3.0)` doesn't calculate the cube root, even if Pow was infinitely precise (which it isn't), because `1.0 / 3.0` is not one third - it's 0.33333333333333331. – harold May 24 '12 at 19:27

2 Answers2

12

Math.Pow(64, 1.0 / 3.0) returns 3.9999999999999996.
This gets rounded to 4 when displayed.

Taking it modulo 1 returns 0.99999999999999956, which is similarly rounded to 1 when displayed.

You can see the true values by adding .ToString("R")

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
3

dCubeRootOf64 % 1 = 1 returns 1 instead 0; cause Math.Pow(i64, 1.0 / 3.0) returns 3.9999999999999996 and 3.9999999999999996 % 1 returns 0.99999999999999956 which in turn getting rounded to 1.

Thus the result 1.

Rahul
  • 76,197
  • 13
  • 71
  • 125