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

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?

What are you ACTUALLY trying to do ? Maybe there is a better algorithm

Steve

Select as Best AnswerUndo Best Answer

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.

Select as Best AnswerUndo Best Answer

There are different methods for calculating slope, slightly, ones that don't involve a division. Look up "Bressenham's algorithm" for some inspiration.

Do you need the sqrt calculation ? You could just work in distance squared units.

Steve

Select as Best AnswerUndo Best Answer

I'll look into this Bressenham's Algoritm...

Do I need sqrt? I use Pythagoras to calculate the "long side"of a triangle (sorry for my English here). I could switch to Sin/Cos or Tan type calculations, but would this make it easier or faster?

Are you thinking of something else?

Select as Best AnswerUndo Best Answer

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?

Select as Best AnswerUndo Best Answer

....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

Select as Best AnswerUndo Best Answer

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...

Select as Best AnswerUndo Best Answer

2mm in total range of.... ?

100 cm ?

Personally, I would write a simulator program to evaluate my routines, before I built the rest of the machine a.) Because you can't break a program. and b.) The hardware may not match your final software !

Steve

Select as Best AnswerUndo Best Answer

Well, I'm more or less doing so...

I have done the calculations and graphs in Excell,

then I compare it to the output of the Arduino (by using a lot of Serial.print commands).

Select as Best AnswerUndo Best Answer

if abs(x) = x then

sign = 1

else

sign = -1

end if

Select as Best AnswerUndo Best Answer

Hey! We

allgot it wrong. Sign(0) == 0. And I just stumbled across an awesomely compact representation:sign(double x) { return ((x>0)-(x<0)); }

where you take the numeric values of the bools, instead of conditionals.

Select as Best AnswerUndo Best Answer

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

Select as Best AnswerUndo Best Answer

I'm glad that somehow I (un-intentionally) improved your understanding! :-)

Select as Best AnswerUndo Best Answer

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.

Select as Best AnswerUndo Best Answer

That adds a function call, which is CPU-expensive (it's a potential long jump). That's why I wrote the direct "if (x<0)" condition.

Select as Best AnswerUndo Best Answer

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

Select as Best AnswerUndo Best Answer

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?

Select as Best AnswerUndo Best Answer

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

willfind 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.Select as Best AnswerUndo Best Answer

Bah, Mine was only pseudocode, not C++. I write real programs in Pascal, and Fortran....

In Pascal

Sgn:=0;

IF number > 0 then sgn:=1

ELSE

if number <0 THEN sgn:=-1;

Besides, I didn't ignore the middle case, I decided to roll it into <0.....

Steve

Select as Best AnswerUndo Best Answer

:-) Yep; the initializer takes care of the zero case (but you didn't initialize in your original version :-).

Select as Best AnswerUndo Best Answer

No, but there were only two states >0 and <= 0.

So nothing stayed undefined :-)

Steve

Select as Best AnswerUndo Best Answer

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:

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.

Select as Best AnswerUndo Best Answer

In addition, be sure to catch the x=xx case for undefined slope before any computations are performed.

We know that only Chuck Norris can divide by zero. :-)

Select as Best AnswerUndo Best Answer

Yes, thanks, my mistake.

Select as Best AnswerUndo Best Answer

IEEE can divide by zero perfectly well. You'll get SlopePower2 = +Infinity or -Infinity depending on the sign of y-yy. If y-yy==0, then you get a NaN.

Select as Best AnswerUndo Best Answer

1.) IF number > 0 then sgn=1 ELSE if number <=0 sgn=-1

2.) You are dividing two integers in the maths, therefore the result is integer1 DIV integer2 and not /

Steve

Select as Best AnswerUndo Best Answer