Float() or (float)

I am on arduino nano (Atmega368) and I am confused about the conversion of variables to float (or any other type).

I tried this, according to the Arduino reference this should work, but it doesn't :

int16_t NSamples = 200;
int32_t sum_Gyro = 0;
float avg_Gyro = float(sum_Gyro);
avg_Gyro /= float(NSamples);

The value returned in avg_Gyro is completely wrong.

This worked :

int16_t NSamples = 200;
int32_t sum_Gyro = 0;
float avg_Gyro = (float)sum_Gyro;
avg_Gyro /= (float)NSamples;

Why ?

Hi, a good question gets a good answer. Can you put more effort in it ?

Can you show a sketch that we can try.
There is a website for that: https://snippets-r-us.com/

The outcome of both is zero. I think that is the correct answer. I stared for a long time at both pieces of code, but the difference does not show, no matter how long I stare at it :wink: Sorry, they are different, see post #7
I don't see "Float" anywhere in the code.

If "Float" is somewhere defined in your Arduino code or libraries, then something is very wrong :astonished:

Please show code between code tags.

Your topic has been moved to a more suitable location on the forum. Please see the sticky topics in Uncategorized - Arduino Forum why you should not post in Uncategorized.

Please use code tags to post the complete code that has the problem.

Yes.

@jesse_a_b perhaps a complete sketch with the real numbers that gave you different results woukd help.

It looks like you are testing a cast

    float x = (float) someInteger;

versus some explicit function.

    float y = Float(someInteger);

Neither is necessary for the calculations as they appear you are doing.

a7

I think you are right, there must be a function or macro that makes the "Float". I have been searching, but there is no "Float" in C or C++ or std or Arduino.

Well, that explains it.

void setup() 
{
  Serial.begin(115200);
  Serial.println(Float(M_PI));
}

void loop() {}

float Float(float x)
{
  return(atan2(sin(x+1),cos(x-1)));
}

Everyone is getting sidetracked by the capitalization of "Float()" in the title. This is actually not the fault of @jesse_a_b, but rather the result of the forum software's behavior of automatically capitalizing the first letter of the title if the topic creator did not do so.

If you look at the actual code posted, you can see the difference is this:

(note it is float with a lower case f)

vs. this:

So it is only about a standard type cast. No mysterious function involved.

These are two different type cast syntaxes. The float(foo) syntax is referred to as "functional" notation. The (float)foo syntax is referred to as "c-like" notation.

The two should be functionally identical in this application. I believe this is the relevant part of the C++11 specification:

https://timsong-cpp.github.io/cppwp/n3337/expr.type.conv#1

the type conversion expression is equivalent (in definedness, and if defined in meaning) to the corresponding cast expression ([expr.cast]).

So I don't have any explanation about why you would get a "completely wrong" value from one and not the other. As already explained, we would need more information to investigate that.

My personal preference is for the "c-like" notation. The reason is that you can't use the functional notation in all applications. For example, you can do this:

(unsigned int)foo

but not this:

unsigned int(foo)
4 Likes

Thank you @ptillisch for making this clear :heart:
In our defense, there was no example sketch :face_with_raised_eyebrow:

If it is just the cast versus the functional notation, then I can easily create very bad code by a integer division versus a float division.

// My ugliest sketch yet

void setup() 
{
  Serial.begin(115200);

  Serial.println(Bad(),10);
  Serial.println(Good(),10);
}

void loop() {}

float Bad()
{
  int16_t NSamples = 200;
  int32_t sum_Gyro = 3;
  float avg_Gyro = float(sum_Gyro/2);
  avg_Gyro /= float(NSamples);

  return(avg_Gyro);
}

float Good()
{
  int16_t NSamples = 200;
  int32_t sum_Gyro = 3;
  float avg_Gyro = (float)sum_Gyro/2;
  avg_Gyro /= (float)NSamples;

  return(avg_Gyro);
}

Result:

0.0049999995
0.0074999995

Try it in Wokwi: My ugliest sketch yet. - Wokwi ESP32, STM32, Arduino Simulator

[EDIT] Replaced "very nasty bug" with "very bad code", since the compiler is indeed just doing what it is told.

That does not seem like a bug, the compiler is doing exactly what it is expected to do, based on what you have told it to do.

float(sum_Gyro/2) uses integer arithmetic for the division, then converts the integer result to a float.

(float)sum_Gyro/2 casts sum_Gyro to a float, then uses float arithmetic for the division.

1 Like

I meant that jesse_a_b might have a bug in the sketch and I created such a thing to cause a difference in the outcome.
I hope that you agree that the sketch that I wrote is very ugly !

that's why we usually ask for a minimum example code that will compile and show the issue at hand... with the Snippets shared by @jesse_a_b it is impossible to tell what's the issue as it's very likely not his real code.

@jesse_a_b ➜ please read How to get the best out of this forum

PS: as a i favour this time, I edited and added the code tags to the first post. Please use code tags when you post code in the future.

I [wi]ll try used this no cast, no functional cast, no function version:

float TraditionlQQ()
{
  int16_t NSamples = 200;
  int32_t sum_Gyro = 3;
  float avg_Gyro = sum_Gyro / 2.0;
  avg_Gyro /= NSamples;

  return avg_Gyro;
}

a7

void setup()
{
  Serial.begin(9600);
  
  int16_t NSamples = 200;
  int32_t sum_Gyro = 0;
  float avg_Gyro = float(sum_Gyro);
  avg_Gyro /= float(NSamples);

  Serial.println(avg_Gyro, 2);
}

void loop(){}

The function float() is not defined and yet the compiler does not report any error message. It is due to the fact that float is a keyword which is known to the compiler.

The compiler has failed to account that a keyword cannot be used as a function name.

OP wants that the integer content (200) of NSamples variable is to be converted into a floating point number (200.0) by a process what is called casting and accordingly he has appended (float) before the variable (for example: float y = (float)NSamples;).

Your example works correctly if you put a proper Serial.begin() into it, it has already been explained that the float() is a proper cast and not an undeclared function.

1 Like

here float() is not a function call.

read Explicit type conversion - cppreference.com, you'll see they mention C-style cast expression and functional-style cast expression

My simple understanding is:
Given:
int y = float(byte a, byte b);

Assuming a new learner of programming language (like the OP) who has not much exposure to C++ Language Specifications including the keywords but has some knowledge about identifiers, I think he will consider that float is an identifier and will immediately accept float() as a function call. I have seen pupils to say that for(); is a function call as they don't know that for is a keyword which can not be used as an identifier.

In the present thread, the OP has no knowledge of the syntax of casting. He has written float(NSamples); instead of (float)NSamples;. I have expected that the compiler will report a warning/error; but, it has not done that. Anyway, you have explained the reason in post #15.

That’s the teacher’s duty ton make sure they get the theory right.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.