simple maths

Hi all,

Sorry if this has been asked before, I tried searching for a while but to no avail. I am trying to do some very simple maths with my arduino uno. I am doing an analog reading from a potentiometer connected to the 3.3V to get a value ranging from 0 to (about) 700. I have verified that this works through Serial Monitor. Then I want to do a very simple mathematical transformation of this value. The transformation I want to achieve is y=xˆ2/490. This is the code I use:

int w = analogRead(A0);
long w2 = w * w * 1L;
long tijd = w2 / 490L;

But it gives strange negative values for variable 'tijd'. Am I using the 'long' command wrong?

Multiplication associates left-to-right, so w * w is done as a 16-bit operation and overflows.

long w2 = 1L * w * w;
or
long w2 = w * (w * 1L);
or
long w2 = (long) w * w;

will fix it, the later being a cast to the long data type.

You may be aware, but the integer division (/ 490) will lose precision.

It would be interesting to test it, but I have not done that.
I would like to force the "w * w" operation into a long calculation.

int w = analogRead(A0);
// make it a long, to be sure the calculation is done with long integers.
long w2 = w;
long tijd = w2 * w2 / 490L;

(While I was writing this, Jack Christensen wrote the same)

Caltoa suggests another variation, and yet another would be:

    long w = (long)analogRead(A0);
    long tijd = w * w / 490L;

It's interesting that the compiler is good enough at optimization that it often produces the same machine code for various permutations like these.

Thank you both! That worked perfectly. I am learning some new stuff about arduino every day :slight_smile:

Jack’s solution used what is called a cast, which involves placing the data type within parentheses before it is used:

long w = (long)analogRead(A0)

What this does is take the 1 byte returned from the analog read of pin A0, and convert it to the 4 bytes the long data type requires. When to use a cast? If w is a long data type, doing this:

int bad;
bad = w;

won’t work well because you are trying to pour 4 bytes of information held in w into a 2-byte bucket named bad, which can result in lost information if it isn’t corrected. The fix is to use a cast:

int bad;
bad = (int) w;

The cast says: Take the 4 bytes from w and reshape it into 2 bytes and assign it into bad. Note, a silent cast:

int bad;
w = bad;

is not a problem because you are taking the contents of a 2-byte bucket and assigning it into a 4-byte bucket. However, good coding practice says to use as cast in this case, too, even though it isn’t required:

int bad;
w = (long) bad;

because it documents your intentions.