![]() |
|
Rounding to nearest 0.05 |
Samuel Henderson
Member #3,757
August 2003
![]() |
I'm trying to figure out how to round to the nearest nickel for a vending machine emulator I am working on. I'm allowing the users to enter a markup percentage that basically raises the prices of all items in the machine by the given percentage. the code I have for this is: //It's one of those coffee vending machines :) void HotLiquid::UpdatePrices(double MarkupPercent) { price = (((MarkupPercent / 100)+1)*price); } So for example ... if the price was $0.50, and the markup is 25% the new price is $.063. I'm going to need to change that to 0.65 .. Whats the best way do this? ================================================= |
miran
Member #2,407
June 2002
|
1. Multiply by 20 EDIT: And code: double round_to_nickel(double price) { return ceil(price*20.0)/20.0; }
-- |
Samuel Henderson
Member #3,757
August 2003
![]() |
Thank you much Miran;D ================================================= |
Billybob
Member #3,136
January 2003
|
For nearest I believe you need: EDIT: Spent a little time to make this puppy // Rounds X to the nearest Y double round(double x, double y) { return floor(x / y + 0.5) * y; }
Quite a work of art if I do say so myself.
|
Samuel Henderson
Member #3,757
August 2003
![]() |
Yeah... I quickly discovered that if the price worked out to something like say 0.601 then it would jump to 0.65. Final formula worked out to: price = floor(price*20.0 +.5)/20.0; Which essentialy is the same as Will's. Thanks again ================================================= |
Arthur Kalliokoski
Second in Command
February 2005
![]() |
Vending machine? No interest calculations? No multi million dollar transactions? Use ints for cents, when displaying, cast to float and divide by 100. EXACT arithmetic every time... They all watch too much MSNBC... they get ideas. |
kentl
Member #2,905
November 2002
|
Without using floor: [edit]: Moved in the type cast |
Billybob
Member #3,136
January 2003
|
I wonder which is faster...not that it matters, just curious. The casting method would result in two casts. One from float->int and then int->float. That compared to whatever floor does...
|
kentl
Member #2,905
November 2002
|
Quote: I wonder which is faster...not that it matters, just curious. Yeah it would be fun to know. I suspect that they would be equally fast, if floor() is implemented using a type cast and gets inlined during compilation. |
Indeterminatus
Member #737
November 2000
![]() |
If I remember correctly, how the cast double->int or float->int works is _______________________________ |
kentl
Member #2,905
November 2002
|
All I ever heard is that all decimal digits are cut off. Which I know they are in at least GCC and Visual Studio (which makes for some pretty good portability). These two sources says nothing about it being implementation specific: |
Arthur Kalliokoski
Second in Command
February 2005
![]() |
floor() needs to do some special stuff so it goes to the larger abs int when negative, and smallest abs int when positive. Simply casting a float to an int takes up some fpu junk with control words etc. which is slow, and floor() and ceil() have to do that and more. They all watch too much MSNBC... they get ideas. |
Thomas Harte
Member #33
April 2000
![]() |
Quote: Whats the best way do this?
Other people have posted perfectly functional ways, but in my opinion the best way (which I consider to mean "neatest" and/or self-explanatory) is with fmod, e.g. [My site] [Tetrominoes] |
Billybob
Member #3,136
January 2003
|
Thomas: That doesn't round, it rounds up only. I did a couple tests out of curiosity and came up with: j up to 1 Modify to run j up to 100 Therefore: Under no optimisations my algorithm is about 3x worse than Kent's. Under optimisations the two algorithms are exactly the same, running at about 769 million calls per second with the for loops and floating point additions.
|
Thomas Harte
Member #33
April 2000
![]() |
Quote: Thomas: That doesn't round, it rounds up only.
You're right - I cannot read. So: Here's a spot fact: the American currency is one of the few not to obey the "halves and doubles of powers of ten" rule, making it a little harder to divide quantities into coins for Americans! [My site] [Tetrominoes] |
Paul Pridham
Member #250
April 2000
![]() |
Here's a simple rounding function I use for some turtle graphics stuff I wrote. double round(double val) { val*=1000; val=(int)(val>=0?val+0.5:val-0.5); val/=1000; return val; }
---- |
Tobias Dammers
Member #2,604
August 2002
![]() |
What Arthur said: ints for cents. int round_to_nickel(int cents) { int mr = cents % 5; return ((mr > 2) ? (cents - mr + 5) : (cents - mr)); } There, a single integer modulo, one check, one sub, and one optional add. And perfect accuracy (although negative numbers will need special care). Splitting into dollars and cents: void cents_to_dollars_and_cents(int v, int& dollars, int& cents) { cents = c % 100; dollars = c / 100; } IIRC, libc has a special function to do both the mod and the div in one step, but I'm too lazy to look it up right now. --- |
|