FAQ
Cover
This is the archive Discourse for the Processing (ALPHA) software.
Please visit the new Processing forum for current information.

   Processing 1.0 _ALPHA_
   Programming Questions & Help
   Syntax
(Moderators: fry, REAS)
   Using floats versus casting to floats
« Previous topic | Next topic »

Pages: 1 
   Author  Topic: Using floats versus casting to floats  (Read 4293 times)
mflux

fluxhavoc WWW
Using floats versus casting to floats
« on: Nov 13th, 2003, 2:51am »

Here is my question:
 
Is it faster to always use floats for any variable that requires decimal values?
 
or
 
Is it faster to always use ints, and cast the ints into a float whenever they need to be applied with decimal calculation?
 
 
Here is an example of what I mean:
 
float x=50;
float a=50/3;
 
OR
 
int x=50;
float a=float(x)/3;
 
 
I'm speaking on a very large and general level where these variables are used thousands of times in very computationally expensive programs. Situations where I'm simulating 10,000 particles, this debate needs to be resolved. Any help would be appreciated, thanks
 
 
 
PS if anyone knows another good way to clock code speed and apply optimization that would be great, I know toxi showed one way...
 
benelek

35160983516098 WWW Email
Re: Using floats versus casting to floats
« Reply #1 on: Nov 13th, 2003, 12:11pm »

if i understood your meaning, the two don't seem to have any real speed differences. I tried the following a few times, with no average difference in times:
 
Code:
for(int i=0; i<1000000000; i++) {
  float x=50;  
  float a=3/x;
}
println(millis());

 
then:
 
Code:
for(int i=0; i<1000000000; i++) {
  int x=50;  
  float a=3/float(x);
}
println(millis());
 
fry


WWW
Re: Using floats versus casting to floats
« Reply #2 on: Nov 13th, 2003, 3:47pm »

if it's floats, then it's faster to keep them all floats.  
 
as it turns out, integer versus float math is less different time-wise in java than in more limited architectures (though doubles take way longer than floats, and longs take way longer than ints.. which is why p5 uses floats), but more overhead comes from converting between ints and floats.
 
toxi

WWW
Re: Using floats versus casting to floats
« Reply #3 on: Nov 13th, 2003, 7:42pm »

totally agree with ben, though in some circumstances there's another viable alternative to float's and int's: fixed point numbers. as you might know the name "float" comes from floating point numbers with a "flexible" precision: the precision decreases the higher the exponent of the number. in almost all cases this is of no major concern, though. only the format of float numbers is not as straight forward to process as an integer number is and hence slightly slower.
 
technically, fixed point numbers are still integers. thanks to the power of your free will, you can "manually" assign some of the 32 available bits to be the fractional part of a given number. you can do that very easily by multiplying a number with a power of 2 value (2,4,8,16,32,etc.). it's all about different interpretations and you already know, multiplying with powers of 2 can also be understood as moving all bits of that integer one or more places to the left:
 
eg. 23 in binary equals:
00000000|00000000|00000000|00010111 = 16+4+2+1
 
23*2 = 46, in binary:
00000000|00000000|00000000|00101110 = 32+8+4+2
 
23*256 = 5888
00000000|00000000|00010111.00000000 = 4096+1024+512+256
 
now, you can see with 8bit precision we can imagine the decimal point to be between the 3rd and the 4th byte and interpret that last byte as the fractional part of our number. at the moment: 23.0 - okay?
 
in general, your precision is exactly defined as 1/pow(2,numberOfBitsShifted). for example using only a 1bit fixed precision gives you a precision of 1/2 (0.5), whereas 8bit precision results in 1/2^8 = 1/256 = 0.00390625 as smallest positive number. in other words, if you need to work with smaller numbers than that you'll need to use a higher precision and sacrifice more bits. i'm saying "sacrificing" because you have to remember that we only have a limited number of bits available to code both the whole and fractional parts, so using more bits for the fraction, leaves you less bits (and therefore scale) for the whole part of the number. it's a tradeoff and how many bits to use, really depends on your circumstances.
 
let's try some basic calculations. pixel transformations are a good area to put our new system to use, as there can easily be a few hundred thousand pixels in an image. so speed is important and even if we just save a few milliseconds, it can be worth it in the long run. the following is slightly unrelated to fixed point math as such, but we'll need it further down the line... internally, the colour of a pixel is "packed" into only one integer number, but is actually encoding 4 independent values: alpha, red, green and blue components, all with a 8bit resolution:
 
Code:
bit31-24|23-16   |15-8    |7-0
aaaaaaaa|rrrrrrrr|gggggggg|bbbbbbbb

 
to easily get the various components in the range of 0-255 we only need to shift the bits right and mask off others not needed using the "&" (binary AND) operator:
 
Code:
int col=get(mouseX,mouseY);
int alpha=(col>>>24);
// result: 00000000|00000000|00000000|aaaaaaaa
int red=(col>>>16) & 255;
// result: 00000000|00000000|00000000|rrrrrrrr
int green=(col>>>8) & 255;
// result: 00000000|00000000|00000000|gggggggg
int blue=col & 255;
// result: 00000000|00000000|00000000|bbbbbbbb

 
lets assume we want to get the greyscale value of that colour. the formula for that is:
 
grey = 0.3*red + 0.59*green + 0.11*blue;
 
to avoid using floats in that equation, let's have a closer look at our RGB values and use our newly aquired knowledge. we know our values are between 0 and 255 or as mentioned before in 8bit resolution. all what's needed now is to transform our hardcoded float factors (0.3, 0.59 and 0.11) into the same 8bit fixed point format by multiplying them with 256.
 
(int)(0.30*256) = 77;
(int)(0.59*256) = 151;
(int)(0.11*256) = 28;
 
so we can rewrite our formula like this: int grey = 77*red + 151*green + 28*blue;
 
now there's only one last very important step missing: re-transformation. as we multiplied everything with 256, eventually we need to undo this if we want to use those values with other "normal" ones, eg. to compare them. so a division by 256 is needed, or faster, shifting the number 8bits to the right, using the ">>" operator. note though that doing so will ofcourse result in the loss of our extra precision as we return to the domain of integers again. so that final operation can also be seen as rounding.
 
Code:
int col,grey,i;
int t0=millis();
for(i=0; i<pixels.length; i++) {
  col=pixels[i];
  // produces a greyscale value in range 0...255
  grey = (77*(col>>16&0xff) + 151*(col>>8&0xff) + 28*(col&0xff)) >>8;
  // version using floats to compare
  //grey = (int)(0.3*(col>>16&0xff)+.59*(col>>8&0xff)+.11*(col&0xff));
  // reset pixel's rgb
  pixels[i]= grey<<16 | grey<<8 | grey;
}
println(millis()-t0);

 
questions?
« Last Edit: Nov 14th, 2003, 1:03pm by toxi »  

http://toxi.co.uk/
REAS


WWW
Re: Using floats versus casting to floats
« Reply #4 on: Nov 13th, 2003, 8:27pm »

thank you VERY much mr toxi for this clear explanation!
 
skloopy

WWW
Re: Using floats versus casting to floats
« Reply #5 on: Nov 13th, 2003, 8:35pm »

How come you don't take equal amounts of R G and B to get a grayscale?
 
grey = 0.3*red + 0.59*green + 0.11*blue;
 
toxi

WWW
Re: Using floats versus casting to floats
« Reply #6 on: Nov 13th, 2003, 8:46pm »

because our eyes have a different sensitivity to red, green and blue hues. do a search for "RGB YUV equation" or "luminance RGB". or try this:
 
http://cnx.rice.edu/content/m11084/latest/
 

http://toxi.co.uk/
mflux

fluxhavoc WWW
Re: Using floats versus casting to floats
« Reply #7 on: Nov 16th, 2003, 8:34am »

Thank you very much Benelekm, Toxi and Ben!!
 
O_O
 
 
it's going to take me a while to digest what you wrote....
« Last Edit: Nov 16th, 2003, 8:35am by mflux »  
Pages: 1 

« Previous topic | Next topic »