I have an Informix-SQL based Pawnshop app which calculates an estimate of how much money should be loaned to a customer, based on the weight and purity of gold. The minimum the pawnshop lends is $5.00. The pawnshop employee will typically lend amounts which either ends with a 5 or 0. examples: 10, 15, 20, 100, 110, 125, etc. They do this so as to not run into shortage problems with $1.00 bills. So, if for example my system calculates the loan should be: $12.49, then round it to $10, $12.50 to $15.00, $13.00 to $15.00, $17.50 to $20.00, and so on!..The employee can always override the rounded amount if necessary. Is it possible to accomplish this within the instructions section of a perform screen or would I have to write a cfunc and call it from within perform?.. Are there any C library functions which perform interval rounding of money values?.. On another note, I think the U.S. Government should discontinue the use of pennies so that businesses can round amounts to the nearest nickel, it would save so much time and weight in our pockets!
I'd just divide by 5, round to the appropriate integer, and multiply by 5.
There might be an easier way but that would work.
The C function round and relatives would do what you ask.
float in_fives = roundf( exact_change / 5. ) * 5.;
There is also rint, which you might avoid because it is not guaranteed to round $12.50 properly.
Related
I'm struggling with an IF statement in Google Docs.
I'm using it financially to find out interest accrued on a value.
Interest is either 1%, 2% or 3% depending on the amount.
If the amount is between £0 and £1999 then 1% is given
If it is between £2000 and £2999 then 2% is given
And anything over £3000 comes to 3%
Here is my attempt:
=IF(M8>=3000,(M8/100)*3,IF(M8<2999),(M8/100)*2,IF(M8<1999),(M8/100)*1)
My thought process here was that it would first check for the >=3000 and work out 3%. If that statement wasn't true it would continue on to the 2% calc and so on.
But this doesn't work. I get "wrong number of arguments for IF" error
You are not closing the IF statements properly and you only need two.
The logic should be: if number is more than or equal to 3000, multiply by 3, if number is less than 3000, but more than 1999(more than or equal to 2000) multiply by 2, in any other case (when number is less than or equal to 1999) multiply by 1.
Here is a working function
=IF(M8>=3000,(M8/100)*3,IF(AND(M8>1999,M8<3000),(M8/100)*2,(M8/100)*1))
Canada announced that they will no longer mint pennies and the U.S. Treasury is strongly contemplating following suit! That implies that monetary amounts will have to be rounded to the nearest nickel, thus requiring a lot of programming modifications!.. In the pawnshop business, we've been rounding loan amounts to the nearest $5 denominations, e.g. 50, 55, 60.. when the calculated loan falls between $50 and $100, to the nearest $10 denomination above $100, etc. Its common practice in order to minimize the use of smaller denomination bills. So what is a good algorithm for rounding to the nearest desired denomination?
In SQL, could I create a user-defined datatype to round to n-denomination, or is it better to leave the decimal(8,2) datatype alone and round with a function?
Assuming that you have your numbers as something like: 44.32, then all you need to do (this is pseudocode, the implementation in c++ should be trivial):
findmod = (num_to_be_changed*100)%5
if findmod <= 2
new_num = num_to_be_changed - findmod
else
new_num = num_to_be_changed + (5 - findmod)
end
new_num = new_num/100
I'd be tempted to use in SQL:
new_val = ROUND(old_value * 20) / 20;
And when nickels go the way of cents, then:
new_val = ROUND(old_value * 10) / 10;
This works fine in SQL with DECIMAL or NUMERIC values; it also works well with SQL FLOAT and a little less reliably with SQL SMALLFLOAT (simply because SMALLFLOAT may only have about 6 decimal digits of accuracy). The same basic technique can be used in C++ if the old_value is a double (more dubiously if it is a float, for the same reason that SQL SMALLFLOAT is problematic). In C++ or C, you'd use the <cmath> or <math.h> header to obtain a declaration for the function round() or roundf(). If you're using ESQL/C and dec_t, then you need decround(&dec_value, 0);.
In ESQL/C, you have provide the number of places to round to, and you'd have to code the multiply and divide, too. Assuming you have a decimal value dec_20 somewhere containing the value 20, you'd write:
dec_t new_val;
decmul(&old_val, &dec_20, &new_val);
decround(&new_val, 0);
decdiv(&new_val, &dec_20, &new_val);
You might error check decmul() and decdiv(); there is no return value from decround() to do an error check on. It is safe to use one of the inputs as the output in the last line.
Not a technical answer per se to the question, but a point to be considered. You may find that your "programmatic modifications" are illusory.
When Australia phased out 1 and 2 cent coins in the 1990s, rounding of amounts was only performed on cash transactions, and this is still the case. Card payments are charged to the cent. Likewise, telephone and other utility bills are charged to the cent, but rounded to the nearest 5c when (and only when) paid in cash over the counter. And of course, share trading and currency exchange continue to be dealt with in fractions of cents or pennies.
So if you can assume that the number of cash transactions rounded down (those ending in 1, 2, 6 or 7c) is roughly the same as the number rounded up (3, 4, 8 or 9c), then the only effect is that the cash register may be out by a few cents at the end of the day. In fact, it is more likely to be up a few cents, because all single item transactions will be rounded up (e.g. every $3.99 purchase is $4.00 in the till.)
There do not have to be any programming changes to support the phase-out of pennies. You can choose to show the rounded amount on printed dockets, but it's not correct to presume anyone is lumbered with a mini Y2K or Euro implementation problem.
First of all this is more of a math question than it is a coding one, so please be patient.
I am trying to figure out an algorithm to calculate the mean for a set of numbers. However I need to neglect any numbers that are not close to the majority of the results. Here is an example of what I am trying to do:
Lets say I have a set of numbers that are similar to the following:
{ 90, 91, 92, 95, 2, 3, 99, 92, 92, 91, 300, 91, 92, 99, 400 }
it is clear for the set above that the majority of numbers lies between 90 and 99, however I have some outliers like { 300, 400, 2, 3 }. I need to calculate the mean of those numbers while neglecting the outliers. I do remember reading about something like that in a statistics class but I cant remember what was it or how to approach the solution.
Will appreciate any help..
Thanks
What you could do is:
estimate the percentage of outliers in your data: about 25% (4/15) of the provided dataset,
compute the adequate quantiles: 8-quantiles for your dataset, so as to exclude the outliers,
estimate the mean between the first and the last quantile.
PS: Outliers constituting 25% of your dataset is a lot!
PPS: For the second step, we assumed outliers are "symmetrically distributed". See the graph below, where we use 4-quantiles and 1.5 times the interquartile range (IQR) from Q1 and Q3:
First you need to determine the standard deviation and mean of the full set. The outliers are those values that are greater than 3 standard deviations from the (full set) mean.
A simple method that works well is to take the median instead of the average. The median is far more robust to outliers.
You could also minimize a Geman-McClure function:
x^ = argmin sum( G(xi - x')), where G(x) = x^2/(x^2+sigma^2)
If you plot the G function, you will find that it saturates, which is a good way of softly excluding outliers.
I'd be very careful about this. You could be doing yourself and your conclusions a great disservice.
How is your program supposed to recognize outliers? The normal distribution would say that 99.9% of the values fall within +/- three standard deviations of the mean, so you could calculate both for the unfiltered data, exclude the values that fall outside the assumed range, and recalculate.
However, you might be throwing away something significant by doing so. The normal distribution isn't sacred; outliers are far more common in real life than the normal distribution would suggest. Read Taleb's "Black Swan" to see what I mean.
Be sure you understand fully what you're excluding before you do so. I think it'd be far better to leave all the data points, warts and all, and come up with a good written explanation for them.
Another approach would be a use an alternate measure like median, which is less sensitive to outliers than mean. It's harder to calculate, though.
I've seen this twice now, and I just don't understand it. When calculating a "Finance Charge" for a fixed rate loan, applications make the user enter in all possible loan amounts and associated finance charges. Even though these rates are calculable (30%), they application makes the user fill out a table like this:
Loan Amount Finance Charge
100 30
105 31.5
etc, with the loan amounts being provided from $5 to $1500 in $5 increments.
We are starting a new initiative to rebuild this system. Is there a valid reason for doing a rate table this way? I would imagine that we should keep a simple interest field, and calculate it every time we need it.
I'm really at a loss as to why anyone would hardcode a table like that instead of calculating...I mean, computers are kind of designed to do stuff like this. Right?
It looks like compound interest where you're generously rounding up. The 100 case + 1 is pretty boring. But the 105 case + 1 is interesting.
T[0] = FC[105] => 31.5
T[1] = FC[136.5] => ?
Where does 136.5 hit -- 135 or 140? At 140, you've made an extra $1.05.
Or... If the rates were ever not calculable, that would be one reason for this implementation.
Or... The other reason (and one I would do if annoyed enough) would be that these rates were constantly changing, the developer got fed up with it, and he gave them an interface where the end users could set them on their own. The $5 buckets seem outrageous but maybe they were real jerks...
I am trying to create a program that will do some simple calculations, but am having trouble with the program not doing the correct math, or placing the decimal correctly, or something. Some other people I asked cannot figure it out either.
Here is the code: http://pastie.org/887352
When you enter the following data:
Weekly Wage: 500
Raise: 3
Years Employed: 8
It outputs the following data:
Year Annual Salary
1 $26000.00
2 $26780.00
3 $27560.00
4 $28340.00
5 $29120.00
6 $29900.00
7 $30680.00
8 $31460.00
And it should be outputting:
Year Annual Salary
1 $26000.00
2 $26780.00
3 $27583.40
4 $28410.90
5 $29263.23
6 $30141.13
7 $31045.36
8 $31976.72
Here is the full description of the task:
8.17 ( Pay Raise Calculator Application) Develop an application that computes the amount of money an employee makes each year over a user- specified number of years. Assume the employee receives a pay raise once every year. The user specifies in the application the initial weekly salary, the amount of the raise (in percent per year) and the number of years for which the amounts earned will be calculated. The application should run as shown in Fig. 8.22. in your text. (fig 8.22 is the output i posted above as what my program should be posting)
Opening the template source code file. Open the PayRaise.cpp file in your text editor or IDE.
Defining variables and prompting the user for input. To store the raise percentage and years of employment that the user inputs, define int variables rate and years, in main after line 12. Also define double variable wage to store the user’s annual wage. Then, insert statements that prompt the user for the raise percentage, years of employment and starting weekly wage. Store the values typed at the keyboard in the rate, years and wage variables, respectively. To find the annual wage, multiply the new wage by 52 (the number of weeks per year) and store the result in wage.
Displaying a table header and formatting output. Use the left and setw stream manipulators to display a table header as shown in Fig. 8.22 in your text. The first column should be six characters wide. Then use the fixed and setprecision stream manipulators to format floating- point values with two positions to the left of the decimal point.
Writing a for statement header. Insert a for statement. Before the first semicolon in the for statement header, define and initialize the variable counter to 1. Before the second semicolon, enter a loop- continuation condition that will cause the for statement to loop until counter has reached the number of years entered. After the second semicolon, enter the increment of counter so that the for statement executes once for each number of years.
Calculating the pay raise. In the body of the for statement, display the value of counter in the first column and the value of wage in the second column. Then calculate the new weekly wage for the following year, and store the resulting value in the wage variable. To do this, add 1 to the percentage increase (be sure to divide the percentage by 100.0 ) and multiply the result by the current value in wage.
Save, compile and run the application. Input a raise percentage and a number of years for the wage increase. View the results to ensure that the correct years are displayed and that the future wage results are correct.
Close the Command Prompt window.
We can not figure it out! Any help would be greatly appreciated, thanks!
Do not store money as floating point. This will end only in tears. Store money as an integral number of cents.
The reason for this is that floating point math on a computer is necessarily inexact. You know that 0.40 / 2 = 0.20, but it's entirely possible that the computer will say it is 0.19999999999999, and that is not an error. The internal representation of floating point numbers makes it impossible for a computer to exactly represent some fractions, much like you cannot write out an exact decimal representation of 1/3 (without an infinite amount of paper).
When you are dealing with numbers that have fractional parts and for which inexactness is not acceptable (e.g. money), you must compute using fixed-point math. In general, you might use a fixed point library, but for an assignment like this, if you're not allowed to do so, an int that stores a number of pennies will do just fine, so long as you understand how integer division works. You will have to write more math code and account for the rounding yourself, though. But that's what you want. You want absolute control over rounding.
I changed your for loop to this:
cout << (i+1) << " $" << wage*52 << "\n";
wage = wage * (1+(raise/100.0));
And it did worked!. I see you didn't understand the language of the problem.
I think that the intention is to receive a 3% raise each year, but you are actually only adding 3% of the starting salary ($780 in this case) each year. You may want to explore modifying the wage value on each pass in the loop (I won't present a solution as I suspect that this is a homework problem, yes?).
The best way to catch this sort of problem is to run it in a debugger and step through each line looking for when the results don't match your expectations. It's usually pretty easy at that point to figure out where your logic went astray.
Your problem is that your program ignores compounding. You are calculating the dollar value of the raise once, and using that for each increase. Once you get your first raise, the value of your second raise needs to be calculated based on your new wage, not your original wage.