croboticslego-mindstormsnxt

Strange behavior when adding longs in RobotC


This is an example of the problem I am encountering with RobotC 3.62:

long heading;
task main()
{
    long num = 0;
    heading=num+90000;
}

This gives the result of heading=24464, which is not what I expected.

I tried replacing the 90000 part with a long containing 90000, and it gave the expected result. It seems as though writing the number 90000 causes some sort of overflow error (90000-256^2=24464). This is odd since a long should hold "A whole number ranging from -2,147,483,648 to 2,147,483,647" . Do I need to cast it somehow? I am not familiar with C, could someone explain this behavior? Thanks!


Solution

  • This is a known issue with 3.X and has been previously fixed for 4.X and is resolved in the current public release of 4.X. There is a workaround for 3.x, however.

    With the code you provided, the compiler output is truncating the result by only doing integer math. This was a previously found bug and later fixed, but still exists in older versions... here's the output:

    long num = 0;
    0025: CB000000 num:S00(slong) = 0 // long/float
    heading = num + 90000;
    0029: BD0800002B000000905F heading:G00(slong) = num:S00(slong) + 90000
    

    As a workaround in 3.X, if you treat the constant as a "float" by specifying 90000.0, the compiler will generate code that will not truncate the long because it'll do 32-bit level math (on the NXT, "int" are actually short ints, hence the truncation)

    long num = 0;
    0025: CB000000 num:S00(slong) = 0 // long/float
    heading = num + 90000.0;
    0029: AD2D04002B0000 S04(float) = num:S00(slong) // Store in temp variable :: Convert 'long' to 'float'
    0030: 902D040000C8AF47 S04(float) += 90000 // Perform <op> on temp variable :: float
    0038: 8C0800002D0400 heading:G00(slong) = S04(float) // Convert 'float' to 'long'