number formats in mathematic expressions

This may be a dumb question but despite some searching I have yet to find the answer.

I have some code that is processing the results from a number of sensor and computing a single number result. The sensor number formats are either float or int. The sensor inputs should only be changing slowly with time and I believe that they are behaving but from time to time the result changes radically and I'm trying to track it down.
One possibility maybe due to the number formats
The key equation in terms of formats it as follows

Float = Float + ((float-float)*int)/(float-float) is this likely to cause problems?

put another way, is any precision lost in the above due to the int variable and so should I make them all floating point?

tia

Bob

is this likely to cause problems?

Maybe. It depends on the last two float values. If they are every equal, look out.

is any precision lost in the above due to the int variable

Dividing a float by an int will promote the int to an float, so you don't need to worry about it.

Thanks for your quick reply
The last two floats differ by about 30.

You said "Dividing a float by an int will promote the int to an float" which is a useful for me to remember but in this case

I'd need the equivalent for what happens when a float is multiplied by and int?

Bob

I'd need the equivalent for what happens when a float is multiplied by and int?

Any time two types are manipulated in a mathematical expression, the types have to be the same. If they are not, the compiler promotes the smaller one to the larger one. So, long * int becomes long * long. float * int becomes float * float.

Problems arise when the promotion doesn't work well. A long can hold fewer values than a float, but more accurately. Promoting a long to a float can result in loss of accuracy.

So, you can't entirely rely on the compiler doing the "right" thing.

OK Thanks Paul,

Sounds like the safe option would be to use all floats for my program.

Cheers

Bob

Sounds like the safe option would be to use all floats for my program.

The safe thing to di is to understand what the compiler is doing, and write code that works correctly when the compiler does what it does. Abstract discussions are entertaining, but specific examples are more useful.

I don't disagree with the principle but finding out what the complier is up to is beyond my skills and I've not seen that level of detail in any documentation.
Bob

Float = Float + ((float-float)*int)/(float-float) is this likely to cause problems?

depending on the actual values there are a number of problems.

  1. division by 0 is recipe for disaster. (discussed above)
  2. The (float - float) can cause overflow (-manfloat - 1 ==> error)
  3. The multiplication with the int can cause a temporary overflow (maxfloat * 2 ==> error
  4. the final addition can cause overflow (maxfloat + 1 ==> error)

So can you give the ranges of every variable: x = a + ((b-c) * i )/ (d-e) // i = int, a,b,c,d,e = float

rewriting the formula can often increase the working range of formulas:
x = a + ((b-c) * i )/ (d-e) ==> x = a + i * ((b-c)/ (d-e) )
As the division makes the float part smaller, the chance on overflow is reduced.

other rewrites
==> x = a + i * ( b / (d-e) - c / (d-e) )
==> x = a + (b - c) * ( i / (d-e) )

depending on the range of the individual vars (and their relative error) an optimal rewrite can be selected (e.g. smallest relative error)

(so far it has little to do with the compiler, just with numerical math)

robtillaart:

Float = Float + ((float-float)*int)/(float-float) is this likely to cause problems?

depending on the actual values there are a number of problems.

  1. division by 0 is recipe for disaster. (discussed above)
  2. The (float - float) can cause overflow (-manfloat - 1 ==> error)
  3. The multiplication with the int can cause a temporary overflow (maxfloat * 2 ==> error
  4. the final addition can cause overflow (maxfloat + 1 ==> error)

So can you give the ranges of every variable: x = a + ((b-c) * i )/ (d-e) // i = int, a,b,c,d,e = float

x is an accumulated value over 7 cycles through the expression and d=c in your equation

so we have x=x+((b-c)*i)/(c-e) // i = int, a,b,c,d,e = float

99 > b > 25
55 > c > 45 and b < c always
80 > i > 25
25 > e > 10

thus (c-e) is always positive and non zero

rewriting the formula can often increase the working range of formulas:
x = a + ((b-c) * i )/ (d-e) ==> x = a + i * ((b-c)/ (d-e) )
As the division makes the float part smaller, the chance on overflow is reduced.

other rewrites
==> x = a + i * ( b / (d-e) - c / (d-e) )
==> x = a + (b - c) * ( i / (d-e) )

depending on the range of the individual vars (and their relative error) an optimal rewrite can be selected (e.g. smallest relative error)

(so far it has little to do with the compiler, just with numerical math)

Thank you for your helpful reply.
Rearranging is an interesting idea and with the further simplification of d=c, some further manipulation is likely to be possible.
For each of the 7 cycles, the values of c and e are fixed and I could therefore perform the division only once at the end of the accumulation, i is an array of 7 fixed constants associated with each value of b and, b is varying for each cycle
At the end of the 7 accumulation cycles the range of values of x tend to lie in the range 0 to 420.

So far, the problem is occurring about once per week with measurements being logged every two minutes. not easy to capture
Math might not even be the problem but it is one possibility.
Certainly food for thought
Kind Regards

Bob

99 > b > 25
55 > c > 45 and b < c always

that means that 55 > b > 25 ?!

robtillaart:

99 > b > 25
55 > c > 45 and b < c always

that means that 55 > b > 25 ?!

Not in practice.
In the event that b=<c, the calculation is abandoned.

Bob

  1. The (float - float) can cause overflow (-manfloat - 1 ==> error)

What is a manfloat? Ice cream and beer?

yes icecream and beer,
more serious it is a typo, I meant MAXFLOAT
defined like here - values.h (no this is not the Arduino define)

and yes -MAXFLOAT -1 will probably rounded by the math lib to - MAXFLOAT,
but you should get the idea, otherwise I’ll explain again :slight_smile:

PaulS:

  1. The (float - float) can cause overflow (-manfloat - 1 ==> error)

What is a manfloat? Ice cream and beer?

Yes sir! I like vanilla ice cream and Coors best. I'm enjoying one right now! It is a ritual I do before checking the surf.
It is the "Breakfast of Champions". :slight_smile: