Allegro.cc Forums » Programming Questions » Rounding down

 Rounding down
 xinco1 Member #8,061 December 2006 Whats the best way of rounding a variable down to the nearest number. For example, if a variable is 99, and I want to round it to a multiple of 32, so the 99 variable is now 96. How do I do this?
 mscava Member #6,815 January 2006 I have to be tired today...
 Matthew Leverton Supreme Loser January 1999 ```x = (x/32) * 32; // or x -= (x % 32) ```
 Andrei Ellman Member #3,434 April 2003 Matthew Leverton said: ```x = (x/32) * 32; // or x -= (x % 32) ``` As 32 is a power of two, the above could be written ```x = (x>>5)<<5; // or x &= 0xFFFFFFE0 ``` But this is unnescesary, as modern compilers will do this optimisation for you. However, if chosing a multiple to round down to, it still helps if you chose one that is a power of two so that the compiler can do these optimisations.AE. --Don't let the illegitimates turn you into carbon.
 X-G Member #856 December 2000 Or better yet (?)...x &= ~0x1f;(Does not assume 32-bit integer.) -- Since 2008-Jun-18, democracy in Sweden is dead. | 悪霊退散！悪霊退散！怨霊、物の怪、困った時は　ドーマン！セーマン！ドーマン！セーマン！　直ぐに呼びましょう陰陽師レッツゴー！
 orz Member #565 August 2000 Minor caveats:x = (x/32) * 32;is not equivalent tox = (x>>5)<<5;or, equivalently, the x &= ~0x1f;for cases were x is negative. The first rounds towards zero, the second rounds towards negative infinity. Quote: But this is unnescesary, as modern compilers will do this optimisation for you. However, if chosing a multiple to round down to, it still helps if you chose one that is a power of two so that the compiler can do these optimisations. Last I checked, if the variable was of an signed type, MSVC would branch on the sign, do the bitwise operations for positive numbers, and for negative numbers first negate, then do the bitwise stuff, then negate the result. All that just to get the correct rounding rules on negative numbers.
 Tobias Dammers Member #2,604 August 2002 I'm wondering whether branching for something this simple is a good idea... if there is a random distribution of positive and negative numbers to be divided, this will kill branch prediction... wouldn't the integer divide be faster on modern hardware in that scenario? ---Me make music: Triofobie---"We need Tobias and his awesome trombone, too." - Johan Halmén
 orz Member #565 August 2000 Quote: I'm wondering whether branching for something this simple is a good idea... if there is a random distribution of positive and negative numbers to be divided, this will kill branch prediction... wouldn't the integer divide be faster on modern hardware in that scenario? I haven't benchmarked the approaches, but my guess would be:Unpredictable sign is very rare. The penalty for mispredict is high (20 to 35 cycles, at a guess), but so is integer division (10-30 cycles at a guess). So, even a 50% mispredict rate is probably not significantly worse than regular integer division. Though, the version with a branch is probably consuming at least a tiny bit of branch prediction resources, and probably minutely lowering the prediction success rate of other branches in the same program. But Microsoft probably did benchmark the approaches before choosing the method they chose (/me crosses his fingers).
 Tobias Dammers Member #2,604 August 2002 It depends on what you use it for.If you do a lot of divisions, and your material is more or less "contiguous" (by that I mean a reasonably accurate discrete representation of a contiguous signal), such as the case in higher-quality audio, or all values have the same sign (such as in e.g. image data), then the branching approach is definitely faster, since there would be only a few or no mispredictions.If, OTOH, you divide only occasionally, or the input values oscillate wildly (sign change on every 3rd value or more), then just dividing is faster.Though I don't think one meets this scenario a lot. ---Me make music: Triofobie---"We need Tobias and his awesome trombone, too." - Johan Halmén
 xinco1 Member #8,061 December 2006 Ok, and what is the best way of rounding up?
 GullRaDriel Member #3,861 September 2003 If it is not a time critical function who need to round your number, then do not take care of any optimization and use x = (x/32) * 32; (as ML said).It will take care of positive/negative value and will avoid you from the (Does not assume 32-bit integer.) thing.Plus, a decent compiler will take care of those sort of optimization for you.Generally, I can tell that you first need to fully develop your application.Optimization should take place once you know that the application is stable and you know which platform will run your code._ "Code is like shit - it only smells if it is not yours"Allegro Wiki, full of examples and articles !!
 Tobias Dammers Member #2,604 August 2002 Quote: Ok, and what is the best way of rounding up? Exactly the same, but before rounding, you add precision-1 to the input. E.g.: ```rounded = ((original + 31) / 32) * 32; ``` ---Me make music: Triofobie---"We need Tobias and his awesome trombone, too." - Johan Halmén
 X-G Member #856 December 2000 Also, Bob wrote this: http://bob.allegronetwork.com/prog/tricks.html -- Since 2008-Jun-18, democracy in Sweden is dead. | 悪霊退散！悪霊退散！怨霊、物の怪、困った時は　ドーマン！セーマン！ドーマン！セーマン！　直ぐに呼びましょう陰陽師レッツゴー！
 xinco1 Member #8,061 December 2006 Ok,thats that problem sorted, but I got another:I need a formula to get the mouse_x and draw it to the screen on a grid. Heres what I got thanks to you guys:(0 + (x % 20) + (mouse_x - (mouse_x % 20)))x is the variable of where the grid is drawn (can be anywhere from -2000 to 0)The problem with this is that when the grid is drawn at -10 for example the mouse is in a grid square while the code equals another how do i fix it??
 Kauhiz Member #4,798 July 2004 Care to actually describe the problem? Also, what is the zero doing in the code? ---It's Ridge Racer! RIIIIIDGE RAAAAACER!
 Tobias Dammers Member #2,604 August 2002 If I understand correctly, you have a tile map that is displayed on screen at a given scroll position, and you want to transform screen coordinates (e.g. from the mouse) into tile coordinates, and possibly back.OK, here goes.I assume that the scroll position is given in screen coordinates, not tilemap coordinates.First, you need to find out where IN SCREEN COORDINATES (that is, pixels) the mouse is relative to the grid origin. This is easy: just subtract the scroll position from it: ```mouse_x_rel = mouse_x - scroll_x; ``` And then you need to transform pixels into tile coordinates. Since a tile is (in your scenario) 20 pixels wide, you must divide the screen coordinates by 20: ```tile_x = mouse_x_rel / 20; ``` Or, in a more general approach: ```tile_x = mouse_x_rel / tile_w; ``` If your tile width happens to be a power-of-two, you can substitute: ```tile_x = mouse_x_rel & (tile_w - 1); ``` ...which is a lot faster.Putting it together: ```tile_x = (mouse_x - scroll_x) / tile_w; // or in case of power-of-two: tile_x = (mouse_x - scroll_x) & (tile_w - 1); ``` The reverse can be found by simply solving the above equation for mouse_x: ```mouse_x - scroll_x = tile_x * tile_w; // <=> mouse_x = tile_x * tile_w + scroll_x; ``` This gives you the upper-left corner of the tile in question; if you want the center, add tile_w / 2 to it.If your tiles are power-of-two-sized, you can substitute left-shift operations for the multiplication, though it's a little less straightforward than the &, especially if you don't hard-code the tile size.--- EDIT ---Oh, and please read this. I could have just answered "By using the correct equation." ---Me make music: Triofobie---"We need Tobias and his awesome trombone, too." - Johan Halmén
xinco1
Member #8,061
December 2006

What i meant was if I had this:

 1 if(mouse_x<10){ 2 x++; 3 } 4 if(mouse_y<10){ 5 y++; 6 } 7 if(mouse_x>630){ 8 x--; 9 } 10 if(mouse_y>470){ 11 y--; 12 } 13 if(x>0){ 14 x=0; 15 } 16 if(x<-2000){ 17 x=-2000; 18 } 19 if(y>0){ 20 y=0; 21 } 22 if(y<-2000){ 23 y=-2000; 24 } 25 draw_sprite(buffer,grid,x,y); //The grid is 20x20 26 draw_sprite(buffer,marker,(x%20)+(mouse_x-(mouse_x%20)),(y % 20)+(mouse_y-(mouse_y%20)));

Thats what I've got. It draws the marker correctly to the grid but it is slightly out. What happens is the mouse is sometimes in one square but the marker is drawn to the square to the left. My question is how can I correct this so that the marker is drawn at the correct place?

 Simon Parzer Member #3,330 March 2003 In your code, what are x and y good for?
 xinco1 Member #8,061 December 2006 X and Y are the positions of where the grid is drawn
 Dustin Dettmer Member #3,935 October 2003 ```int makePow2(int x) { x--; x |= (x >> 1); x |= (x >> 2); x |= (x >> 4); x |= (x >> 8); x |= (x >> 16); x++; return x; } ``` This is the code I'm using to upsize my textures to a power of 32.
 Bob Free Market Evangelist September 2000 Dustin said: This is the code I'm using to upsize my textures to a power of 32. And you can find an explanation for it here. --- Bob [ -- All my signature links are 404 -- ]
 Dustin Dettmer Member #3,935 October 2003 Quote: And you can find an explanation for it here [bob.allegronetwork.com]. Whenever you link to that page I always think how useful the thing is. But then when I actually need it I've forgotten it exists.
 Go to: Allegro Development Installation, Setup & Configuration Allegro.cc Comments Off-Topic Ordeals The Depot Game Design & Concepts Programming Questions Recent Threads