Division defaults to int when passed 2 ints.

Former Member
Former Member
oddity = 7 / 3.0;
Sys.println("oddity = " + oddity);
oddity = 7 / 3;
Sys.println("oddity = " + oddity);
oddity *= 2;
Sys.println("oddity = " + oddity + " // Note that the value right of the decimal is lost.");
oddity = 5 / 3.0;
Sys.println("oddity = " + oddity + " // Proving that division will always round down.");
oddity = 5 / 3;
Sys.println("oddity = " + oddity);
oddity = 5 / 3.toFloat();
Sys.println("oddity = " + oddity + " // Have to add toFloat() to at least one of the variables to ensure precision.");


oddity = 2.333333
oddity = 2
oddity = 4 // Note that the value right of the decimal is lost.
oddity = 1.666667 // Proving that division will always round down.
oddity = 1
oddity = 1.666667 // Have to add toFloat() to at least one of the variables to ensure precision.


So as you can see division will round down when passed 2 ints.
  • This is the way that most programming languages work (C, C++, Java, Python, ...). It is a simple arithmetic conversion. In the cases you present it is a specific type of conversion called a binary numeric promotion). The result is that the type of the arguments control the type of the result.

    While MonkeyC is a new language, its roots are from Java, Python, and Ruby, all of which have these rules.

    Java
    Python
    Ruby

    Given that MonkeyC is duck-typed, the actual type that is the result of the expression is hidden. If you want to be sure you get a value that isn't rounded down, you need to have at least one argument in the operation be of floating-point type.

    Travis
  • Former Member
    Former Member over 10 years ago
    OMG. I never realized you needed to be quite so specific. I would have though something like the following would have been safe.

    double myNum = 2/3;


    But alas no.... oh dear.
  • Former Member
    Former Member over 10 years ago
    ...... you need to have at least one argument in the operation be of floating-point type.

    Although, doesn't this break that rule?
    var precision = 1.1 * 0.6;
    Sys.println("precision = " + precision);

    var noPrecision = 1.1 * (2 / 3);
    Sys.println("noPrecision = " + noPrecision);

    precision = 0.660000
    noPrecision = 0.000000
  • No, (2/3) is an integer division resulting in 0, the next step will be 1.1 * 0, which will result in a float -> 0.0
  • Sorry I explained only half of the problem (why you get a float when there is one or more floats involved). When both are integers you get an integer and the result is truncated because of integer division rules as pointed out by STEWA285.
  • Travis is correct that we are using similar rules as Ruby and Python. Here's a chart that explains the result type of a +-*/ operation. (I = int, F = float, L = long, D = double)

    [FONT=Courier New]
    x|I F L D
    ---------
    I|I|F|L|D
    F|F|F|D|D
    L|L|D|L|D
    D|D|D|D|D
    [/FONT]

    As Travis points out, because 2 / 3 is 0, it zeroes out your operation, but 2f / 3f would work.
  • Former Member
    Former Member over 10 years ago
    Ok, thanks. I will make sure that necessary casting is done.