Archived

This topic is now archived and is closed to further replies.

GekkoCube

integer to fraction conversion.

Recommended Posts

GekkoCube    116
this seems like a trivial problem, but i cant think of a good solution to this... Lets say I divide 240 by 32 then say I mod 240 by 32 i get two answers, 7 and 5. Now I would like to convert 5 to 0.5 What would be an easy way to do this? If the mod value was 25 then it would have to convert to 0.25 Thanks, edward ~ I''''m a wannabe programmer ~

Share this post


Link to post
Share on other sites
Fruny    1658
exp = 1+(int)(log(x)/log(10));
x = (float)x / pow(10,exp);

Edit: check if x != 0 first, otherwise log will barf.

Edited by - Fruny on January 29, 2002 4:31:32 PM

Share this post


Link to post
Share on other sites
GekkoCube    116
whoaw.
this is not trivial at all, atleast not in my humble opinion.
i''ll try this out, meantime, i hope somebody will post other cool ideas for this conversion.

thanks anyways

~ I''''m a wannabe programmer ~

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
if the above works then don''t read this

but you could also just keep dividing by 10 until you result is less than 1...

Share this post


Link to post
Share on other sites
Fruny    1658
quote:
Original post by GekkoCube
this is not trivial at all, atleast not in my humble opinion.



I assure you it is.

What it does is find the smallest power of 10 larger than your number and divide by it. log() is the base-e log function, and what you want is the base-10 log. You have log10(x) = log(x)/log(10). You then add 1 and truncate by casting to an int.

e.g.

x = 5, exp = 1, pow( 10, exp ) = 10, -> x = 0.5
x = 25, exp = 2, pow( 10, exp ) = 100, -> x = 0.25

Share this post


Link to post
Share on other sites
GekkoCube    116
strange, i tried the log method, and im not getting the right answer.

ill try it again even harder, but to clear things up does this look right?

int mod = 240 % 32;
int exp = 1 + (int)(log(mod)/log(10));
float fraction = (float)(mod/pow(10,exp));
int offset = (int)(32 * fraction);

this looks like what you wrote, but im not getting the right answer (which should be 16 for this case).





~ I''''m a wannabe programmer ~

Share this post


Link to post
Share on other sites
BSXrider    122
quote:

int mod = 240 % 32;
int exp = 1 + (int)(log(mod)/log(10));
float fraction = (float)(mod/pow(10,exp));
int offset = (int)(32 * fraction);



Should work. mod = 16. exp = 1 + (int)1.2... = 1+1 = 2

fraction 16/10*10 = 0.16

- seb

Share this post


Link to post
Share on other sites
a person    118
just to let you know, 240%32 while equal to 16 does not make the fractional portion 0.16 it makes it 16/32.0f

beyond that, why are you converting the remainder to the greatest number below 1 where the divsor is a power of 10? maybe i am naive but i am seeing very little use for this, unless this is for numbers between 0 and 0.31 that have very little bearing on the remainder?

please explain GekkoCube, or any one else for that matter. oh well, maybe i am looking at things too simply since i dont see how useful the fraction you are creating use the exp method is when dealing with offsets. if any one could explain a good use for this trick, please explain. since i am tucking this away with all those other, crazy math tricks that may be useful someday.

EDIT: silly typo, teach me to trust math from a person asking the question, heh.

Edited by - a person on January 29, 2002 10:25:45 PM

Share this post


Link to post
Share on other sites
TerranFury    142
I don''t think youundersand what mod returns.

Mod returns the remainder of division.

240 / 32 = 7
240 % 32 = 16

You take the remainder over the divisor to get the fraction. What this tells you is 240/32 equals 7 and 16/32. Take 7+16/32 and you''ll find that it equals 7.5.

Share this post


Link to post
Share on other sites
EvilCrap    134
the fastest way to put a decimal in the front of a number:

    
int base = 10;
while(x > 1) x/=base;// this is 5+ times faster than the fruny



Edited by - evilcrap on January 29, 2002 10:04:46 PM

Share this post


Link to post
Share on other sites
GekkoCube    116
Evilcrap, I am assuming you mean:

float x = value;
while(x > 0.0f)
{
x = x / 10.0f;
}

This way we can actually get a fractional value instead of the quotient from simply dividing.
Again, I am assuming you mean this..?

How do you place code snippets in a nice block of color???


I was trying to get this offset due to a project im working on.
It has very little or no meaning in an actual game...but let''s just say I had to do this!

thanks.

~ I''''m a wannabe programmer ~

Share this post


Link to post
Share on other sites
Brother Bob    10344
GekkoCube, your while loop will either finnish immediately, or never finnish.

If x is positive, then x will never ever become less than zero if you keep on dividing by 10 (a positive number divided by a positive number is never a negative number). In that case, the while loop will never exit.

If x is negative, it will exit before it enters, since x is less than zero when the loop starts.

PS. You put code between the [ source ] and [ /source ] tags (without spaces in the tags, of course).

Share this post


Link to post
Share on other sites
a person    118
again i dont see the relevance to using mod and fractions. if you are simply trying to take a whole number and making into the greatest fraction below 1.0 that has a divsor that is a power of 10 then use evilcraps method or the other method shown (both work well). though to correct EvilCrap AND GekkoCube

  
while(x>=1)
x/=10.0f;


whether this is fatser or not however is up in the air. i have not done a benchmark no care to since this has not too many uses in game development. in homework however...

Share this post


Link to post
Share on other sites
DrPizza    160
Always always always do reciprocal multiplication if you can.

If you''re doing anything like either of these:
  
double* arr = new double[1024];
for(size_t i = 0; i < 1024; ++i)
{
arr[i] /= 10.0;
}

or
  
double* arr = new double[1024];
double div = calculateSomeValue();
for(size_t i = 0; i < 1024; ++i)
{
arr[i] /= div;
}

Then calculate the reciprocal outside the loop and multiply.

Reciprocal multiplication is significantly faster than division (such that you only need to loop a small number of times for it to be worthwhile).

Share this post


Link to post
Share on other sites