3021Views26Replies

# Two questions: 1. How do I calculate a "sign" with Arduino? 2. I have difficulties with fractions. Answered

Since these are two questions in one go, I'll be rewarding a patch!!!

Question 1
How do I calculate the sign of a number?
e.g. Sign(-3)=-1
e.g. Sign(5)=1

I could use an equation like: (-3)/(sqrt((-3)*(-3))) but that would be time consuming. Is there a function avalable?

Question 2
Consider the following program

int Xcoord[]={12,17,23,25,22,29,33,32,35};
int Ycoord[]={15,13,16,20,23,26,22,19,15};
int xCount = 9;
int x;
int y;
int a;
int xx;
int yy;
float SlopePower2;

void setup() {
Serial.begin(9600);
}

void loop() {
for (int a = 1; a < xCount; a++)
{
int xx=Xcoord[a-1];
int yy=Ycoord[a-1];
int x=Xcoord[a];
int y=Ycoord[a];

SlopePower2=((y-yy)/(x-xx))*((y-yy)/(x-xx)) ;

Serial.print("SlopePower2 =");
Serial.print(SlopePower2);
Serial.println();
delay(5000);
}
}
//end

An Array is used to read numbers (this works fine).Then the power of the slope is calculated. Sometimes this number is larger than 1 (then the calculation works fine). However when the calculated value is between 0 and 1 ( a fraction thus)  it is rounded off to either 0 or 1 (although I have assigned it as a "float"). Why?

Tags:

## Discussions

That's TOP SECRET! :-)
(I'm trying to build a robot for the contest).
It gets part of its input from a set of arrays X and Y (what I showed is part of the entire program). With this it has to calculate the slope and the distance between two points (x and y).
slope=dy/dx
distance=sqrt(dy*dy+dx*dx)
These are pretty basic equations, I don't think there is a alternative.

However, your comment has made me think of the following:

In the loop x and y are taken from the array's. Then dx and dy are calculated, then the slope and the distance are calculated (and some other stuff).
Would it be faster to to do the following?
In the setup() part of the program, quickly read the entire X and Y array and then fill a new Array with all the dx's, fill a new a Array with all the dy's, fill a new Array with all the new dy/dx.

In this way a large part of the calculation is kept out of the Loop(), making it faster (becaus in the Loop() only values of an Array have to be read instead of calculated).

Does this make sense? If so, how do I fill an Array that is a result of a calculation.

I was trained as a Petroleum Engineer and as I consequence, I try to solve all my problems with a pipe wrench. This Arduino stuff is pretty new to me.
You have pointed out an algorithm that's been around since the sixties and I never heared of it. That's humbling (thanks!).
I'll have to study it closer though.

What about the idea of reading out the arrays in the Setup() phase. Would that help / work?

....and I work in instruments for measuring Lubricants. You're not with Shell are you ?

You could look at the potential values from your distance calculations, and use a look-up table.

Ask yourself (and tell me !!) what the practical resolution you need from your distance measurement is.

There are all SORTS of clever tricks you can do in an embedded system that aren't taught anywhere.

Steve

No, not with Shell. Moreover, nowadays I work in the field of renewable energy (biomass).

Practical resolution? If the Array is in cm, then I guess I need an accuracy of 2mm.

I'm very much interested in your ideas, but they are a bit "intimidating" as well. I have an idea for which I need to figure out a lot of stuff as it is:
1. The routines (currently discussing).
2. Getting the servos to work (in combination with the routine).
3. Building the mechanical parts.

If I introduce other algorithms (which I currently do not master) then my project becomes more complex. Maybe I should take the project as far as possible with "classic" algorithms and then come back to you for "the need for speed"?
We could eventually turn it into a collaboration if required...

This method performs integer math on values returned from boolean operators which in C always returns 1 for True and 0 for False.

I'm old-school and got too many other computer languages on the brain.  In other languages sometimes FALSE is 0 and TRUE is Not 0 and not necessarily 1.

I didn't realise that in all implementations of C, boolean operators returning true is always return 1.

Thank you for improving my understanding!

Best Wishes

You're welcome! In C (and C++) an operation returning a boolean value has true => 1, false => 0. However, the converse is more general: an operation returning an _integer_ value may be interpreted as boolean with 0 => false, any non-zero => true.

This is why you can write null-pointer checks in the form "if (!pointer) got-a-null-here;" Only the zero pointer will resolve that expression to true.

In FORTRAN, things are different, FALSE=0 still, but TRUE=-1.

My first answer to (1) was not correct. I don't feel too badly about that, because Nacho and Steve got it wrong, too! The correct expression is

sign(x) = +1 for x>0, 0 for x==0, and -1 for x<0

(I ignored the middle case). Doing a Web search, I found a beautifully compact representation, which uses the boolean numeric values (true=1, false=0) to compute the result without conditionals
`int sign(double x) { return (x>0) - (x<0); }`

Ha, ha, ha. You guys are making it hard to select the best answer with all the mistakes!
No but seriously, the effort is highly appreciated and for one, Í didn't know the answer in the first place.

I was surprised by the extreme compact suggestion you made. I have never seen it in the "classic" text books. Is this a variation of some kind?

You won't find things like that in introductory textbooks, because it is likely to confuse students learning the language. What you're doing is relying on the internal representation of "bool" types as integral values, and implicit casts to do the arithmetic. The result is well-defined (and documented, for example, in K&R).

You will find a lot of that stuff in more advanced textbooks, generally in discussions of code optimization. That's also where you're likely to find some of the really obfuscatory tricks like using bit-shift operations for specialized arithmetic, the use of "register" variables, and so on.

1) Don't use an equation, since you'll have divide-by-zero problems. Just use the ternary operator:
`int sign(double x) { return x<0 ? -1 : 1; }`

2) Your slope comes back as an integer because all of its operands are integers. Look at K&R, Chapter 2 (I think). If you want to compute a floating point ratio, you need to cast the operands to float:
`SlopePower2 = float(y-yy)/float(x-xx);SlopePower2 *= SlopePower2;`

Note: Don't calculate the ratio twice; that's a waste of time. Also, take the declarations out of the loop; that's allocating extra and unused memory.