3 Simple Ways to
Share What You Make

With Instructables you can share what you make with the world — and tap into an ever-growing community of creative experts.

PhotosPhotos

Share one or more photos of a project, recipe, or whatever you've made, quickly and easily.

Step by StepStep-By-Step

Share your step-by-step photos with text instructions of what you made so others can do it too!

VideoVideo

Share your how-to video. You'll need your embed code from a video site such as YouTube.

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?

26 answers
sort by: active | newest | oldest
Feb 15, 2011. 1:26 PMsteveastrouk says:
What are you ACTUALLY trying to do ? Maybe there is a better algorithm

Steve
Feb 16, 2011. 12:09 AMsteveastrouk says:
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
Feb 16, 2011. 2:00 AMsteveastrouk says:
....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
Feb 16, 2011. 3:46 AMsteveastrouk says:
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
Feb 15, 2011. 1:56 PMNachoMahma says:
if abs(x) = x then
  sign = 1
else
  sign = -1
end if
Feb 15, 2011. 2:56 PMkelseymh says:
Hey! We all got 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.
Feb 16, 2011. 7:03 AMmaewert says:
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
Feb 16, 2011. 7:20 AMkelseymh says:
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.
Feb 15, 2011. 2:53 PMkelseymh says:
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.
Feb 15, 2011. 2:59 PMkelseymh says:
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); }
Feb 16, 2011. 7:29 AMkelseymh says:
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.
Feb 15, 2011. 3:11 PMsteveastrouk says:
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
Feb 15, 2011. 3:22 PMkelseymh says:
:-) Yep; the initializer takes care of the zero case (but you didn't initialize in your original version :-).
Feb 15, 2011. 3:38 PMsteveastrouk says:
No, but there were only two states >0 and <= 0.
So nothing stayed undefined :-)

Steve
Feb 15, 2011. 12:56 PMkelseymh says:
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.
Feb 15, 2011. 2:43 PMmaewert says:
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.  :-)
Feb 15, 2011. 3:00 PMkelseymh says:
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.
Feb 15, 2011. 12:53 PMsteveastrouk says:
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

Pro

Get More Out of Instructables

Already have an Account?

close

All Steps Viewing
View all steps of an Instructable on the same page when you're a Pro Member.

Upgrade to Pro today!