Page 1 of 1

NXC: Type conversion problems

Posted: 08 Nov 2011, 17:45
by afanofosc
I have had a report of issues with the latest test release of NXC that involve converting between floats and ints. Matthew if you could respond here with the problems you have encountered I'd be grateful. If anyone else could run some tests with the latest test release and let me know here or via email what problems you run into that would be awesome.

John Hansen

Re: NXC: Type conversion problems

Posted: 08 Nov 2011, 18:40
by mattallen37
Run this program:

Code: Select all

task main(){
  int int_22 = 22;
  int int_7 = 7;
  Wait(0);
  float result1 = int_22 / int_7; //This used to work
  Wait(0);
  float result2 = int_22;         //Now I have to use this...
  result2 /= int_7;               //... and this to get the floating point result
  Wait(0);

  NumOut(0, LCD_LINE1, result1);
  NumOut(0, LCD_LINE2, result2);
  while(true);
}
I am fairly sure the results used to be the same, but now they are different.

However, if I use global variables like this:

Code: Select all

int int_22 = 22;
int int_7 = 7;
float result1;
float result2;

task main(){

  Wait(0);
  result1 = int_22 / int_7; //This works
  Wait(0);
  result2 = int_22;         // and this works
  result2 /= int_7;         //       ''
  Wait(0);
  
  NumOut(0, LCD_LINE1, result1);
  NumOut(0, LCD_LINE2, result2);
  while(true);
}
I get results as expected (they are both floating point numbers).

I haven't tried isolating the exact place that makes the difference, and I haven't tried static "local" variables. NXC doesn't support type casting, so I obviously can't test it with that either.

BTW, the reason for the Wait(0);s is so that it is easier to identify the operations in NBC.

I also just noticed that I had my compiler optimization set to 1, instead of 2 (no idea why I would have changed it...). That makes a difference (2 works as expected for local variables).

I guess the issue I found is when the optimization is 1, and I use local variables.

Re: NXC: Type conversion problems

Posted: 11 Nov 2011, 04:11
by muntoo
mattallen37 wrote:

Code: Select all

task main(){
  int int_22 = 22;
  int int_7 = 7;
  Wait(0);
  float result1 = int_22 / int_7; //This used to work
  Wait(0);
  float result2 = int_22;         //Now I have to use this...
  result2 /= int_7;               //... and this to get the floating point result
  Wait(0);

  NumOut(0, LCD_LINE1, result1);
  NumOut(0, LCD_LINE2, result2);
  while(true);
}
The expected output is:

Code: Select all

3
3.142857
Is it something different?

This is how it should work:

Code: Select all

f = 22/7;
f = float(22/7); // 'coercion' or implicit type conversion
f = float(3);
f = 3.0;

Re: NXC: Type conversion problems

Posted: 11 Nov 2011, 17:55
by mattallen37
Muntoo, I don't agree with you, and neither does the compiler on optimization level 2. Also, neither does another compiler I use. If I use a type cast float(), even if I enter constants, it should output the value in float... or else the type cast is mostly pointless...

Re: NXC: Type conversion problems

Posted: 11 Nov 2011, 19:03
by HaWe
I don't understand yet where the problem is.
I agree with muntoo that for integer division integer/integer this would be expected as far as I observed NXC hitherto:

Code: Select all

f = 22/7;
f = float(22/7); //no type conversion
f = float(3);
f = 3.0;
If one of the deviding numbers was float, then I would expect a type coast to float:

Code: Select all

f = 22.0/7;
f = float(22.0/7); //implicit type conversion
f = float(3.142857);
f = 3.142857;
Of course both should happen no matter which O.L. or if they were global or local variables.
What exactly happens at what time to your observations, Matt?

Re: NXC: Type conversion problems

Posted: 11 Nov 2011, 19:23
by muntoo
In C, types are usually converted at the last possible moment. For example,

Code: Select all

f = (10*14 + 4) / 10 * 1.0f;
f = float(EVALUATE_THIS_FIRST);
Will evaluate the expression on the rhs (right-hand side). Since none of the values are of type float, no type conversions take place there. (Type conversions are expensive.)

After that, we go into the brackets, and do the multiplication, then addition, followed by division, and lastly, multiplication again.

Code: Select all

f = (140   + 4) / 10 * 1.0f;
f = (144      ) / 10 * 1.0f;
f = 14               * 1.0f;
f = float(14)        * 1.0f;
f = 14.0                   ;
f = 14.0; // Implicit conversion to float is unnecessary.
See? Types are only converted at the last possible moment; this is partly due to performance reasons, but it's also more logical that way, IMHO.

See also: 4.4 — Type conversion and casting.

Re: NXC: Type conversion problems

Posted: 11 Nov 2011, 20:32
by HaWe
muntoo,
that's more or less the same as I said (with Matt's example).
But what's Matt's problem which he observed (concerning O.L. and local or global declarations)?

ps
If I really NEED to avoid unexpected a/o unwanted results I meanwhile use this:

Code: Select all

inline float FLOAT(long x){return(x);}