I don’t know if it just my lack of knowledge of C++ of a known fact I should know but forgot, because I’m trying to learn or mostly in my case re-learn , python , c++ , JavaScript , etc.

My problem.

int val = analogRead(A0);
float volts = val / 621 ;
Serial.println( volts );

int val = analogRead(A0);
float volts = val / 621;

Since val is an int, and your constant 621 is also an int, the division result is an int. The result is truncated to an integer and then assigned to a float, resulting in the value 4.0.

In the second example:

float val = analogRead(A0);
float volts = val / 621 ;

val is now a float so the division includes both a float and an int. This results in a floating point division with a float result being assigned to the float volts.

If you want to ensure floating point arithmetic, be sure that at least one of the operands is a float or double.

You could also have done this:

int val = analogRead(A0);
float volts = val / 621.0;

Notice that the constant is now a float. Again one operand is a float so the result is a float.

This is the way arithmetic operators work in C/C++. In your first code fragment your variable val is an integer type. On the next line the division operation divides val by 621, also an integer. The rules of the language are that the result of the division operation will be an integer type regardless of the type of the variable you are assigning the result to. If either of the arguments to the division operator are a float, then the result of the division will be a float. So if you typecast one of the arguments of the division operator to a float it would have returned a float to the variable volts, (e.g. float volts = (float)val / 621;). You’d also get a float result if you wrote the equation as float volts = val / 621.0, because now 621.0 is a float.