:(
编写一个程序,计算所有权第一年的新房年税后成本。成本是按年度
抵押成本减去节税额计算得出的。输入的应该是房屋的价格和预付款。每年的抵押贷款成本可以
估计为初始贷款余额的\ $ 3 \%\ $,用于支付
贷款本金加上初始贷款的\ $ 6 \%\ $
利益平衡。初始贷款余额是价格减去预付定金。假设边际税率为\ $ 35 \%\ $,并假定利息支付可抵扣税款。因此,节税为利息支出的\ $ 35 \%\ $
。您的程序应至少使用两个
函数定义,并应允许用户根据用户的意愿重复进行此
计算。
我可能已经欺骗了我需要的两个函数定义...
mortgage.cpp
:/**
* @file mortgage.cpp
* @brief Computes the annual after-tax cost of a new house
* @author syb0rg
* @date 10/9/14
*/
#include <cctype>
#include <iostream>
#include <limits>
/**
* Makes sure data isn't malicious, and signals user to re-enter proper data if invalid
*/
long double getSanitizedDouble()
{
long double input = 0.0L;
while(!(std::cin >> input) || input < 0)
{
// clear the error flag that was set so that future I/O operations will work correctly
std::cin.clear();
// skips to the next newline
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "Invalid input. Please enter a positive number: ";
}
return input;
}
/**
* Safetly grabs and returns a lowercase version of the character (if the lowercase exists)
*/
char32_t getSanitizedChar()
{
// absorb newline character (if existant) from previous input
if(std::cin.peek() == '\n') std::cin.ignore();
return std::tolower(std::cin.get());
}
int main()
{
do
{
long double housePrice = 0.0L;
long double downPayment = 0.0L;
// get input for house price, re-read input if not a positive number
std::cout << "Enter the price of the house: $";
housePrice = getSanitizedDouble();
// get input for down payment, re-read input if not a positive number
std::cout << "Enter the down-payment: $";
downPayment = getSanitizedDouble();
long double loanBalance = housePrice - downPayment;
long double interest = .06 * loanBalance;
long double annualMortgage = (.03 * loanBalance) + interest;
long double savings = .35 * interest;
long double totalCost = annualMortgage - savings;
std::cout << "The annual after-tax cost of the house is $" << totalCost << std::endl;
std::cout << "Run the program again (y/N): "; // signify n as default with capital letter
} while ('y' == getSanitizedChar());
}
#1 楼
我建议进行一些较小的更改:用符号常量替换魔术数字。当这些费率发生变化时,
修改程序会更容易。
constexpr long double ANNUAL_MORTGAGE_COST = 0.03;
constexpr long double LOAN_PRINCIPAL_PLUS = 0.06;
constexpr long double MARGINAL_TAX_RATE = 0.35;
我建议不要将其放入函数中,而不是在
main()
内进行计算。 long double totalPayment(long double housePrice, long double downPayment){
long double loanBalance = housePrice - downPayment;
long double interest = LOAN_PRINCIPAL_PLUS * loanBalance;
long double annualMortgage = (ANNUAL_MORTGAGE_COST * loanBalance) + interest;
long double savings = MARGINAL_TAX_RATE * interest;
long double totalCost = annualMortgage - savings;
return totalCost;
}
评论
\ $ \ begingroup \ $
也许用const引用代替?仅出于效率和安全性考虑。
\ $ \ endgroup \ $
–user54356
2014年10月7日在17:28
\ $ \ begingroup \ $
@Dave通常认为内置类型足够快,可以按值传递。
\ $ \ endgroup \ $
–莫文
14-10-7在17:29
\ $ \ begingroup \ $
您已在利息和年度抵押贷款计算中切换了ANNUAL_MORTGAGE_COST和LOAN_PRINCIPAL_PLUS。如果将它们分别命名为PRINCIPAL_REDUCTION_RATE和INTEREST_RATE,这可能会更明显。
\ $ \ endgroup \ $
– Brythan
2014年10月7日17:30
\ $ \ begingroup \ $
@Brythan好抓住。
\ $ \ endgroup \ $
–user54356
2014年10月7日17:37
#2 楼
要完成已经说过的一些小事情。几乎没有一个是有意义的,但是好的实践是好的实践。您不需要使用
std::endl
:它会打印换行符并刷新缓冲区,从而这里不需要。您可以简单地使用\n
。这样做不会对您的程序造成影响,但这仍然是一个好习惯。注意:正如@Emily所指出的,它仅刷新用于缓冲输入的缓冲区,情况并非如此为
std::cout
,除非手动将其重定向到文件。无论如何,我都会在这里保留此评论,这不是因为我仍然相信这是一种很好的做法,而是因为了解它可能仍然有用。 。没有必要在housePrice
块的开头声明它们。downPayment
返回getSanitizedDouble
。虽然这很好,但返回do {} while ()
(返回类型为getSanitizedChar
)或char32_t
可能更有意义,因为您是从int
的实例std::tolower
读取的。您在
char
中使用了错误的文字,应该是std::cin
(哈哈,找到一个:p)。也有人说这是风格问题,许多人不喜欢它,但是将大括号放在单语句
std::basic_istream<char>
上是个好习惯。如果每个苹果开发人员都做到了这一点,那么臭名昭著的while(!(std::cin >> input) || input < 0)
漏洞就不算什么了。评论
\ $ \ begingroup \ $
在std :: endl上使用\ n是一个样式问题,我更喜欢使用后者。在某些情况下,使用\ n可以避免代价高昂的缓冲区刷新,但我认为始终使用\ n会过早优化。更多信息:stackoverflow.com/a/25569849/2498188
\ $ \ endgroup \ $
–艾米莉·L。
2014年10月7日19:31
\ $ \ begingroup \ $
+1代表“有人说这是风格问题”-我一直在编码if(condition)doif(); else doelse();多年以来,直到最近(根据自己的意愿)才切换到if(condition){doif();} else {doelse();}-我对此很满意,主要是因为我没有键入那些括号使用IDE自动格式化/自动补全功能,同时兼顾两种解决方案的优点(安全性+少键入)-尽管我可以说,经过激烈的编辑后,剩下的花括号让整个代码的格式搞砸了,这有点恼人。
\ $ \ endgroup \ $
–user20300
2014年10月8日13:47
#3 楼
你确实被骗了。出于一个问题的考虑,使函数能够计算总成本更加合理:double total_cost(double balance);
至少您可以重用它长达数年的总成本。来。
评论
我知道这是家庭作业,但我仍然必须警告所有读者在处理金钱时应使用浮点数。这是一个很大的禁忌。四舍五入的错误将很快累积,金钱将会流失。 stackoverflow.com/questions/3730019/…@EmilyL。非常像办公室的空间
@sjagr当然,Office Space中的家伙们以《超人III》为灵感:)