CAST float to int unexpected results

I've been getting unexpected results when trying to convert a FLOAT to an INT.

int recastVar = (int)newDouble;

In my script when my double = 8.0, the recast int value returned is 7. The script below illustrates the problem that I'm having. This has had me rather confused for the past few hours. To note when the float = 9.0 or 7.0, the INT returned is 9 and 7 respectively.

Any help would be very welcome!

double myDouble = 6.9;																	


void setup()
{
	Serial.begin(9600);
}

	
void loop()
{	
		cast_num();
		
		delay(2000);
}

void cast_num()
{
	if (myDouble == 9.5)
	{
		myDouble = 6;
	}
	
	myDouble = myDouble + 0.1;
	
	double newDouble = myDouble;
	
	int recastVar = (int)newDouble;
	
	Serial.print ("float: ");
	Serial.println(newDouble);
	
	Serial.print ("re-cast: ");
	Serial.println(recastVar);
	
	Serial.println(" ");

}
if (myDouble == 9.5)
   {
      myDouble = 6;
   }

myDouble is never set to 6

You can't cast variables of different sizes with any meaning. It makes no sense to do that.

Just assign the float to an int. The compiler KNOWS how to truncate the float to fit into an int. It does not need your ham-fisted "help".

lowsecmail:
I've been getting unexpected results when trying to convert a FLOAT to an INT.

That's because a float represents a decimal floating point number using binary internally... it is not exact for fractions.

See: This converter which shows the internal representation
That example shows that the closest a float can get to the decimal 7.9 is actually the decimal value 7.900000095367431640625.

This is why your float value incremented by 0.1 never actually equals 9.5

Because of this close-but-not-exact nature of float values, if you force the value to an int it truncates the float value, so 7.999999 becomes the integer 7

If you really want to do this for some reason, then you would be correct in writing:

int recastVar = (int)newDouble;

because that shows your explicit intent to cast the number to integer.

What you may want to do is round the number to the nearest integer.

int recastVar = round( newDouble );

This will convert 7.4 into 7 and 7.6 into 8 for example.

If you want to truncate the floating point number in such a way that your current program displays anything from 7.0 to 7.9 as 7 and 8.0 to 8.9 as 8 then there are several ways to do that, for example:

int recastVar = (int)floor( newDouble + 0.0001);

where the floor() function returns a float with the "decimals removed", that addition of 0.0001 makes sure that a value like 7.999999 becomes 8.000099, floor() returns 8.00000 which then truncates to 8

Yours,
TonyWilk

P.S. Serial.print() actually does some rounding of floating point numbers which is why it is printing a value like 8.00 when, internally, it is actually something like 7.999999.
Try:

  float fred= 7.999999;
  Serial.println( fred );

If you want to truncate the floating point number in such a way that your current program displays anything from 7.0 to 7.9 as 7 and 8.0 to 8.9 as 8 then there are several ways to do that, for example:

int recastVar = (int)floor( newDouble + 0.0001);

where the floor() function returns a float with the "decimals removed", that addition of 0.0001 makes sure that a value like 7.999999 becomes 8.000099, floor() returns 8.00000 which then truncates to 8

Tony you are awesome. This is exactly what I was looking to do. Thanks for your help.