Not so easy math


#1

I am struggling to get some functionality in my object for which I need a division.

I have entered the following expressions:
outlet_test1 = (64-24)*(64/40);
outlet_test2 = (64-24)*1.6;

In easy math they have the same outcome. In not so easy math they have a different outcome. Can anyone point me in the direction how I should change the first line to get the outcome of the second line?


#2

I guess this is just a basic C question... (rather than about integer maths as is used in axo.)

assuming so, then your issue with C, is 'type conversion'
C will keep its type, so your 64/40 is done as an integer and so equals 1, if you want to use floating point then you have to tell C to upcast it to float (or double or whatever :wink:)

in this constant example, you can do this by using float constants
e.g. (64-24) * (64/40.0f) , this results in a float expression

this is why your second example 'works' , since you have given it a float, and so will use float for the expression

(40.0 will also work, but is considered bad practice, as its unclear... it could be a double or could be float, depending on compiler/platform... many compilers will now give a warning for this. )

however, Id recommend you read up about type conversion in C, its an important topic, and one if you are not clear on is really easy to get yourself in a mess, and introduce some subtle (=nasty) bugs.
(e.g. things like operator precedence might change which parts of your expression are in float, and which in int)


#3

I think what you want to do is change the first line to

outlet_test1 = (64-24)*64/40;

or, clearer but with redundant parentheses, as multiplication and division take place in left to right order anyway.

outlet_test1 = ((64-24)*64)/40;

As @thetechnobear noted, when 64/40 is evaluated in integer maths, the result is 1, så you loose the fractional part. The trick in integer math is to multiply the whole value with 64 before dividing with 40; that way, you don't get the decimal truncation until the the final value. If you really want to be accurate, add 20 (half of 40) before the division, to get the result properly rounded, i.e.

outlet_test1 = ((64-24)*64+20)/40;

The downside is because you're potentially multiplying your value with a fairly large integer (64) it will overflow before the division is performed; in the above example this won't happen, at least not with integers that are 16 bits wide or more, but I'm suspecting the expression is a simplification of a more complex expression involving variables, in which case you need to check your expression with the largest possible input value to check that it doesn't overflow in that case.


#4

Thank you Mark for pointing me in the right direction.

You are right about that!