View Single Post
  #14   Spotlight this post!  
Unread 19-02-2007, 21:25
Bongle's Avatar
Bongle Bongle is offline
Registered User
FRC #2702 (REBotics)
Team Role: Mentor
 
Join Date: Feb 2004
Rookie Year: 2002
Location: Waterloo
Posts: 1,069
Bongle has a reputation beyond reputeBongle has a reputation beyond reputeBongle has a reputation beyond reputeBongle has a reputation beyond reputeBongle has a reputation beyond reputeBongle has a reputation beyond reputeBongle has a reputation beyond reputeBongle has a reputation beyond reputeBongle has a reputation beyond reputeBongle has a reputation beyond reputeBongle has a reputation beyond repute
Send a message via MSN to Bongle
Re: Looping a function

Quote:
Originally Posted by Tz0m View Post
Even if I make everything a float the terminal prints blank spaces for the results. Also, do I multiply the final answer by 1000 or do I multiply before hand?
Apparently printf has issues with floating-point output. To fix that, do this:

// suppose your result is in variable myFloat
int iTemp = (int)(myFloat*1000.0f)
printf("result is %d divided by 1000",iTemp);


If you want to go the faster fixed-point method, then I'd suggest writing a bunch of defines to make sure that you don't screw up a multiply or divide.

#define FIXP 1024
#define FIXP_MULTIPLY(x,y) ( (x * y)/FIXP )
#define FIXP_DIVIDE(x,y) ((x*FIXP) / y)
#define FIXP_ADD(x,y) (x+y)
#define FIXP_SUBTRACT(x,y) (x-y)
#define FIXP_TO_FLOAT(x) ( (float)x/FIXP )
#define TO_FIXED_POINT(x) (x*1024)
It looks uglier, but it'll keep you from forgetting normalizing a value.

Intro to fixed-point numbers:
Basically, what you're doing is saying: 1024 in my fixed-point system equals 1. So an integer holding 512 REALLY means 0.5, one holding 768 means 0.75, etc. This way, you can simulate decimal points without having to do all the complicated (and very computationally expensive) floating-point calculations.

The reason that multiply and divide are different is because you're system is based on this idea:
fixedPoint(x) = 1024*x

fixedPoint(x)*fixedPoint(y) = (1024*x)*(1024*y) = 10242xy
but
fixedPoint(x*y) = 1024*(x*y) = 1024xy

So we need to divided the multiply result by 1024 in order to get the correct result.

Anyway, your function changed to use these fixed-point #defines would look like:
Code:
#define FIXP 1024
#define FIXP_MULTIPLY(x,y) ( (x * y)/FIXP )
#define FIXP_DIVIDE(x,y) ((x*FIXP) / y)
#define FIXP_ADD(x,y) (x+y)
#define FIXP_SUBTRACT(x,y) (x-y)
#define FIXP_TO_FLOAT(x) ( (float)x/FIXP )
#define TO_FIXED_POINT(x) (x*1024)

float DistanceCalc(int tiltS)
{
// tiltS is between 0 and 255, let's make it fixed-point
int fixp_tiltS = TO_FIXED_POINT(tiltS);

int tiltD, tiltR, dist;
tiltD = ((fixp_tiltS - TO_FIXED_POINT(124)) * 65) / 124;
// tiltD is fixed-point because divides/multiplies by non-fixed-point numbers don't affect that
tiltR = (tiltD * 3.14159265) / 180.0;
// tiltR is fixed-point for the same results tiltD was
dist = (float)(TO_FIXED_POINT(80.0)) / float(tan(tiltR));
// dist is NOT fixed point because it got divided out
return dist;
}
If you have a programming mentor, ask them about the basics of fixed-point math.

A good way to think about it is to just imagine doing all your math with the decimal place moved to the right, and if you ever want to find out your 'real' number, you just have to move the decimal back to the left.
Example:
You have 3.14 and 2.71. You want to multiply them and find the result.
1) Represent them as 3140 and 2710.
2) Multiply them to get a result of 8509400, but that's HUGE! If we move the decimal place to the left again, then we'd be saying 3.14*2.71 is 8509! That's because of the multiplication issue I discussed above.
3) If we move the decimal place back to the left 3 places first, we get 8509.
4) Then if we want to know the result in real numbers, we move it again, and get 8.509, which is actually (close to) correct.

This was kind of a stream-of-thought post, I hope it helped. Do a google search for it. A basic fixed-point math system is really quite simple to implement.