Main Menu

Accel Variable

Started by hakcenter, July 27, 2015, 10:41:54 PM

Rx7man

the particular instance here

float final_sum = 0.0f;

you could just declare as

float final_sum = 0;

and it would be the same thing.. you only need the "f" when there's math involved... right?
'94 dually,  67/67 HE351VE, NV5600, ~600hp
'93 ECLB 47RH, new toy truck, H pump project, 1000hp goal, 300K miles
93 XCLB auto, bone stock, 350K miles
93 XCLB 5spd, bone stock, 100K miles

hakcenter

#16
If you don't add the .0, it won't kick into float math it'll be stuck in int math.. I think it has more to do with the compiler than anything else really.

https://www.arduino.cc/en/Reference/Float
Quote
If doing math with floats, you need to add a decimal point, otherwise it will be treated as an int. See the Floating point constants page for details.

I'm not sure if you can sneak in casting to float and not need the .0 though
TS2009 Deḇarim 8:2
"And you shall remember that יהוה your Elohim led you all the way these forty years in the wilderness, to humble you, prove you, to know what is in your heart, whether you guard His commands or not.

Rx7man

I think you only need to at the .0 when dealing with literals


float var1 = 1;
float var2 = 2;
float var3 = var1/var2;

that should work as expected, that is, var3 = 0.5, because the math is being done on 2 floating point numbers... in the line where var3 is assigned, it has no 'knowledge' of if you declared var2 as '2' or '2.0', they're stored the same way
'94 dually,  67/67 HE351VE, NV5600, ~600hp
'93 ECLB 47RH, new toy truck, H pump project, 1000hp goal, 300K miles
93 XCLB auto, bone stock, 350K miles
93 XCLB 5spd, bone stock, 100K miles

hakcenter

#18
Without the decimal place, those will be treated as integers and upon compiling will evaluate to 0.

Read the link from Arduino.
https://www.arduino.cc/en/Reference/Float
https://www.arduino.cc/en/Reference/Fpconstants


   int x;
   int y;
   float z;

   x = 1;
   y = x / 2;            // y now contains 0, ints can't hold fractions
   z = (float)x / 2.0;   // z now contains .5 (you have to use 2.0, not 2)

x had to be type casted to float, to get 0.5 and the division requires 2.0 not 2.

Compiler optimizations and what not. Float math is avoided cause its slow.
TS2009 Deḇarim 8:2
"And you shall remember that יהוה your Elohim led you all the way these forty years in the wilderness, to humble you, prove you, to know what is in your heart, whether you guard His commands or not.

Rx7man

yes, that's true, you're using literals.. in my example the math was done on floats, but assigned without using the '.0'


int var1 = 1;
int var2 = 2;
float var3 = var1;
float var4 = var2;

float var5 = var1/var2; //returns 0   the types are integers
float var6 = var3/var2; // should return 0.5, one of the variables is a float, forcing floating point math
float var7 = var3/var4; //returns 0.5, both are floats


I think that's right.
'94 dually,  67/67 HE351VE, NV5600, ~600hp
'93 ECLB 47RH, new toy truck, H pump project, 1000hp goal, 300K miles
93 XCLB auto, bone stock, 350K miles
93 XCLB 5spd, bone stock, 100K miles

hakcenter

Quote from: Rx7man on August 26, 2015, 08:50:47 AM
yes, that's true, you're using literals.. in my example the math was done on floats, but assigned without using the '.0'


int var1 = 1;
int var2 = 2;
float var3 = var1;
float var4 = var2;

float var5 = var1/var2; //returns 0   the types are integers
float var6 = var3/var2; // should return 0.5, one of the variables is a float, forcing floating point math
float var7 = var3/var4; //returns 0.5, both are floats


I think that's right.


int var1 = 1;
int var2 = 2;
float var3 = (float) var1;
float var4 = (float) var2;

float var5 = var1/var2; //returns 0   the types are integers
float var6 = var3/(float) var2; // should return 0.5, one of the variables is a float, forcing floating point math
float var7 = var3/var4; //returns 0.5, both are floats


Now yes... if you put an int into a float, it uses int math.
TS2009 Deḇarim 8:2
"And you shall remember that יהוה your Elohim led you all the way these forty years in the wilderness, to humble you, prove you, to know what is in your heart, whether you guard His commands or not.

Rx7man

I had to try it

void setup() {
  // put your setup code here, to run once:
Serial.begin(115200);
int var1 = 1;
int var2 = 2;
float var3 = var1;
float var4 = var2;

float var5 = var1/var2; //returns 0   the types are integers
float var6 = var3/var2; // should return 0.5, one of the
float var7 = var3/var4; //returns 0.5, both are floats

Serial.println(var5);
Serial.println(var6);
Serial.println(var7);


}

void loop() {
  // put your main code here, to run repeatedly:

}


returns:
0
0.5
0.5

int to float conversion is done implicitly in var3=var1, you don't need to specify it
'94 dually,  67/67 HE351VE, NV5600, ~600hp
'93 ECLB 47RH, new toy truck, H pump project, 1000hp goal, 300K miles
93 XCLB auto, bone stock, 350K miles
93 XCLB 5spd, bone stock, 100K miles

hakcenter

Nice to see it goes against what they say, wonder if its the same throughout the IDE versions
TS2009 Deḇarim 8:2
"And you shall remember that יהוה your Elohim led you all the way these forty years in the wilderness, to humble you, prove you, to know what is in your heart, whether you guard His commands or not.

Rx7man

it should...

when you're converting the literal 2 to a float, it gets converted implicitly so there's no need to put the decimal on it, you only need to specify it when using literals as they could be any type.. like '1' could be a boolean, float, double, or integer, and there's no way of knowing if it even should be stored with the sign bit... so if you want it to be a float, you need either the ".0" behind it of 'f'
'94 dually,  67/67 HE351VE, NV5600, ~600hp
'93 ECLB 47RH, new toy truck, H pump project, 1000hp goal, 300K miles
93 XCLB auto, bone stock, 350K miles
93 XCLB 5spd, bone stock, 100K miles

hakcenter

I understand the basic logic. But when you read their documentation and their code example its wrong.

They type cast x, when it is unnecessary. They also stated that unless you use point 0 or f, the compiler uses integer math.

Best to pull the machine code to see if using a float = 2/3 saves memory and time versus float = 2.0 / 3

Or if they are the same anyways.
TS2009 Deḇarim 8:2
"And you shall remember that יהוה your Elohim led you all the way these forty years in the wilderness, to humble you, prove you, to know what is in your heart, whether you guard His commands or not.

Rx7man

I don't know if I've forgotten how to program, but I am unable to test how fast it works either way... no matter how many loops I make it do, it's always saying 4 microseconds... I don't believe it... I'll figure it out someday I guess
'94 dually,  67/67 HE351VE, NV5600, ~600hp
'93 ECLB 47RH, new toy truck, H pump project, 1000hp goal, 300K miles
93 XCLB auto, bone stock, 350K miles
93 XCLB 5spd, bone stock, 100K miles

Rx7man

Quote
Best to pull the machine code to see if using a float = 2/3 saves memory and time versus float = 2.0 / 3

float = 2/3 will be done in integer math because you're using integer literals

'94 dually,  67/67 HE351VE, NV5600, ~600hp
'93 ECLB 47RH, new toy truck, H pump project, 1000hp goal, 300K miles
93 XCLB auto, bone stock, 350K miles
93 XCLB 5spd, bone stock, 100K miles

hakcenter

#27
If it all lands up on the same micros, then its most likely creating the same code both ways.

Take the elf and run it against obj-dump

windows bat file

@echo off
cls
echo Disassembler for the .elf file by avr-objdump.exe
rem Place avr-objdump.exe and this batch file in the same folder
rem Don't use filenames with spaces

avr-objdump -S name_of_elf.elf > assembler.txt
pause



void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
int var1 = 1;
int var2 = 2;
float var3 = var1;
float var4 = var2;

float var5 = var1/var2; //returns 0   the types are integers
float var6 = var3/var2; // should return 0.5, one of the
float var7 = var3/var4; //returns 0.5, both are floats

Serial.println(var5);
Serial.println(var6);
Serial.println(var7);


}

void loop() {
  // put your main code here, to run repeatedly:

}


My big grimace about doing things this way, is making the assumption that var1 and var2 are type casted to float, without the typecast. The assumption is float test = int 1 + int 2; is a float, when its coming in as ints, to me shows inequal types. I would expect float test = (float) (int 1 + int 2);


int var1 = 1;
int var2 = 2;
int var3 = var1;
int var4 = var2;

float var5 = var1 / var2;
float var6 = (float) var3 / var2;
float var7 = (float) var3 / (float) var4;


When I read that, I see var5 as int math, my expectation is var5 is a float for size even though an unsigned long would probably be just as good.

Where as var6 and var7, I know that the purpose is to have a decimal place with actual division.

I imagine in compiling the type castings are removed/ignored, but it does help other readers understand the implicit goal. Why Arduino states their compiler uses int math wherever an int is not type casted is beyond me, when you've already shown it doesn't. I would like to think maybe older compilers in the older IDE's probably did. Who knows, there could be a difference between windows avr-gcc+ and linux avr-gcc+. I know that in my testing I'm strictly using my Gentoo laptop while I'm mobile code testing, versus sometimes I bring the lbb in at my desk and compile on my desktop (w7).

I will say that, assumptions can really put a cork in coding. Haha. Like when you send a negative number to the turbo, and it makes it 3cm^2 instead of 25cm^2. How it became negative was someone made the assumption (me haha) that this particular math wouldn't go negative or need constraints. Assumptions like the arduino map() command constrains at the start and end points, where as it actually just creates a slope between 2 numbers, so it will continue that linear way in either direction. :-D
TS2009 Deḇarim 8:2
"And you shall remember that יהוה your Elohim led you all the way these forty years in the wilderness, to humble you, prove you, to know what is in your heart, whether you guard His commands or not.

Rx7man

the "map" function is documented as saying it does NOT apply constraints though :P


int var1 = 1;
int var2 = 2;
int var3 = var1;
int var4 = var2;

float var5 = var1 / var2;
float var6 = (float) var3 / var2;
float var7 = (float) var3 / (float) var4;


where 
float var5 = var1/var2, the compiler knows that both types are integer *types*, thus cannot be anything other than an integer

but
float var8 = var3/var4, the compiler knows that both types are float *types*, but holding an integer *value*... it only cares about the type, so it does floating point math

take this for example

int var1 = 20;

for (float i = 1; i<5; i +=.5){
  float result = var1 / i;
  Serial.println(result);
}

in this example, every other iteration through the loop it will be an integer *value*, while the underlying type remains float.
If it did the math based on the value stored, every time i was an integer value, the result would be calculated with integer math, and be wrong...
the right results are
1
1/1.5 (whatever that works out to in decimal)
.5
1/2.5
1/3
etc

while the wrong results if it did integer math when the value rather than type was an integer
1
1/1.5
0
1/2.5
0
1/3.5
'94 dually,  67/67 HE351VE, NV5600, ~600hp
'93 ECLB 47RH, new toy truck, H pump project, 1000hp goal, 300K miles
93 XCLB auto, bone stock, 350K miles
93 XCLB 5spd, bone stock, 100K miles

hakcenter

Pretty sure you missed what I said up above lol.
TS2009 Deḇarim 8:2
"And you shall remember that יהוה your Elohim led you all the way these forty years in the wilderness, to humble you, prove you, to know what is in your heart, whether you guard His commands or not.