提问人:shampeyndadi 提问时间:11/16/2023 最后编辑:shampeyndadi 更新时间:11/17/2023 访问量:75
根据给定的工资计算要缴纳的所得税
Compute for the income tax to be paid based on the given salary
问:
编写一个程序,询问员工的工资,并根据给定的工资计算要支付的所得税。使用以下方案进行税款计算:
前 2 比索为 1000% 接下来的 7 比索为 2000% 剩余价值为11%
#include <stdio.h>
int main()
{
float salary, incometax;
printf("Enter salary: ");
scanf("%f", &salary);
if (salary <= 1000)
{
incometax = salary * 0.02;
printf("Income tax to be paid: %.2f\n", incometax);
}
else if (salary <= 2000)
{
incometax = salary * 0.07;
printf("Income tax to be paid: %.2f\n", incometax);
}
else if (salary > 2000)
{
incometax = salary * 0.11;
printf("Income tax to be paid: %.2f\n", incometax);
}
return 0;
}
我不知道我所做的是否正确
更新
#include <stdio.h>
int main()
{
float salary, incometax;
printf("Enter salary: ");
scanf("%f", &salary);
if (salary <= 1000)
{
incometax = salary * 0.02;
printf("Income tax to be paid: %.2f Pesos\n", incometax);
}
else if (salary < 3000)
{
incometax = (salary - 1000) * 0.07 + (1000 * 0.2);
printf("Income tax to be paid: %.2f Pesos\n", incometax);
}
else
{
incometax = ((salary - 3000) * 0.11) + 2000 * 0.07 + 1000 * 0.02;
printf("Income tax to be paid: %.2f Pesos\n", incometax);
}
return 0;
}
我相信它是这样的。不过,如果我的条件是正确的,我不会。请检查。韦尔普
答:
1赞
Allan Wind
11/16/2023
#1
不,您的计划没有正确实施边际税规则。例如,工资为 4000 比索,您的计划说所得税是 0.11 * 4000 = 440,但应该是 0.02 * 1000 + 0.07 * 2000 + 0.11 * 1000 = 270。
下面是一个实现:
#include <stdio.h>
double incometax(double salary) {
double incometax = 0;
if(salary < 0)
incometax += 0;
else if(salary <= 1000)
incometax += 0.02 * (salary - 0);
else
incometax += 0.02 * ( 1000 - 0);
if(salary < 1000)
incometax += 0;
else if(salary <= 3000)
incometax += 0.07 * (salary - 1000);
else
incometax += 0.07 * ( 3000 - 1000);
if(salary < 3000)
incometax += 0;
else
incometax += 0.11 * (salary - 3000);
return incometax;
}
int main(void) {
double salary;
printf("Enter salary: ");
scanf("%lf", &salary);
printf("Income tax to be paid: %.2lf\n", incometax(salary));
}
或更简洁地与三级运营商():?:
double incometax(double salary) {
return
0.02 * (salary <= 0 ? 0 : (salary <= 1000) ? salary - 0 : 1000 - 0) +
0.07 * (salary <= 1000 ? 0 : (salary <= 3000) ? salary - 1000 : 3000 - 1000) +
0.11 * (salary <= 3000 ? 0 : salary - 3000);
}
税收规则可能会发生变化,因此最好将其表示为数据(可能从文件、数据库或网站等外部来源读取)。在研究上述两个解决方案时,您可能还注意到,它们对 3 条规则中的每一条都重复了相同的内容。这意味着使用循环。最后,观察到规则的最高边际工资与规则的最低边际工资相同:i
i+1
#include <values.h> // MAXDOUBLE
double incometax(double salary) {
static const struct {
double min;
double rate;
} rules[] = {
{0, 0.02},
{1000, 0.07},
{3000, 0.11},
{MAXDOUBLE, 0}
};
const size_t n = sizeof rules / sizeof *rules;
double incometax = 0;
for(size_t i = 0; i < n - 1; i++)
incometax += rules[i].rate * (
salary <= rules[i].min ? 0 :
salary <= rules[i+1].min ? salary - rules[i].min :
rules[i+1].min - rules[i].min
);
return incometax;
}
评论
0赞
Allan Wind
11/16/2023
别客气。如果这回答了您的问题,请单击它旁边的复选标记来接受它。
0赞
Peter - Reinstate Monica
11/17/2023
#2
这是一个精心设计的程序,具有以下功能:
- 接受最高约 1.8 * 1013 个单位(卢比、美元等)的收入。
- 精确计算美分。
- 接受来自命令行或 stdin 的数据。
- 当 stdin 为终端时提示。
- 处理输入错误。
- 即使在终端上,也可以简单地粘贴多个分隔的数字, 无需每行一个(下面的第 6 个输入提示)。
也许除了实际算法之外,还有一些东西在这里很有用:
- 使用可以传达错误的返回类型 ()。
struct ParseResult
- 使用 和其他输入函数的返回值来检测输入错误,并将其与文件末尾区分开来。
scanf
- 将外观相似的代码移动到参数化函数中,而不是复制它(使和都小)。
MakeParseResult()
ParseIncomeInHundredthsFromString()
ParseIncomeInHundredthsFromStream()
- 有些算法非常适合递归,比如这个算法 ()。
computeTaxes()
- 将输入与处理分开(对 I/O 一无所知)。
computeTaxes()
- 就像 Allan 的回答一样,不要在代码中硬连接数据(数组可以从某个地方读取)。
taxSteps
- 注意取值范围(32 位对于高收入来说是不够的,更不用说美分或卢比了)。
- 在 和 中使用正确的转换说明符,此处为: 和 。这有点麻烦,但对于便携性是必要的。不同的实现对 typedef 具有不同的本机数据类型,因此需要不同的转换说明符(例如,Linux 上的转换说明符就是 Windows 上的转换说明符)。
printf()
scanf()
PRIu64
SCNu64
uint.._t
%ul
%ull
- 尽管它不是标准的 C,但一些常见的 Posix 函数(如在非 Posix 实现中)也可用。它们很有用。
isatty()
示例会话:
$ gcc -Wall -o income-tax income-tax.c && ./income-tax.exe
Tax brackets:
0.00 .. 1000.00: 2.00%
1000.00 .. 3000.00: 7.00%
Above: 11.00%
Please input income values in a format like '12345.99 ...'
1000.00
Taxes for 1000.00: 20.00
Please input income values in a format like '12345.99 ...'
3000.00
Taxes for 3000.00: 160.00
Please input income values in a format like '12345.99 ...'
10000.00
Taxes for 10000.00: 930.00
Please input income values in a format like '12345.99 ...'
10000.10
Taxes for 10000.10: 930.01
Please input income values in a format like '12345.99 ...'
1234.56 7890.89 121212121212.12
Taxes for 1234.56: 36.41
Please input income values in a format like '12345.99 ...'
Taxes for 7890.89: 697.99
Please input income values in a format like '12345.99 ...'
Taxes for 121212121212.12: 13333333163.33
Please input income values in a format like '12345.99 ...'
$
从命令行和每个管道:
$ ./income-tax.exe 1500.00 4500.25 1234567890123.00
Taxes for 1500.00: 55.00
Taxes for 4500.25: 325.02
Taxes for 1234567890123.00: 135802467743.53
$ echo "1500.00 4500.25 1234567890123.00" | ./income-tax.exe
Taxes for 1500.00: 55.00
Taxes for 4500.25: 325.02
Taxes for 1234567890123.00: 135802467743.53
//*************************************************
// A tax computing program for a multi-step tax bracket.
// The brackets are specified in the taxSteps array.
// The program is currency agnostic but assumes a
// "unit" and "hundredths" (Dollar/Cent, Euro/Cent, Pound/Penny).
// It stores money values in those "hundredths" (e.g. Cents)
// using 64 bit integers. (32 bit would not quite be enough
// for the highest earners; Elon Musk payed $11bn in 2021.)
// The tax rate is likewise stored in 1/100s of a percent
// to facilitate non-integer tax rates.
// All arithmetics are integer; resulting taxes are rounded down.
//
// The program accepts input as commandline arguments
// ("income-tax 1234.56 777.88") or from standard input
// ("echo 1234.56 777.88 | income-tax").
// Iff standard input is a terminal it issues a prompt.
#include <stdio.h>
#include <stdint.h> // for 64 bit type
#include <assert.h>
#include <limits.h> // uint64_max
#include <inttypes.h>
#include <stdlib.h> // exit
#ifdef _MSC_VER // microsoft compiler, as opposed to *nix environment
# define _CRT_SECURE_NO_WARNINGS // silence MSVC
# pragma warning(disable : 4996) // MSVC prefers _isatty
# include<io.h>
#else
# include <unistd.h>
#endif
// Convenience function because of the unwieldy format strings.
// Prints "a string like "123.45" from 12345.
void printHundredths(uint64_t Hundredths)
{
printf("%" PRIu64 ".%02" PRIu64, Hundredths / 100, Hundredths % 100);
}
/// A single tax step: An interval in centi-money units with a rate in "centipercent".
struct TaxStep
{
uint64_t StepSizeInHundredths;
unsigned int TaxRateInHundredthPercent;
};
uint64_t computeTaxesInHundredthsForStep(uint64_t incomeInHundredths, struct TaxStep taxStep)
{
uint64_t taxedInThisStep
= incomeInHundredths < taxStep.StepSizeInHundredths
? incomeInHundredths
: taxStep.StepSizeInHundredths;
// Such a high income would overflow in the expression below and compute
// a tax amount that's much too low. The threshold, for 100% tax, is
// > 1.8E15 Hundredths, or 1.8E13 whatever (dollars, rupees). In rupees
// we get close to a realistic income (one rupee ~ 1 cent), 1.8E12,
// 1.8 trillion dollars. If, say, Elon Musk liquidates its entire
// stock at the zenith of his wealth, in Rupees or Lira, we could come close.
// Let's say that's OK for now.
if ( taxStep.TaxRateInHundredthPercent != 0
&& taxedInThisStep > UINT64_MAX / taxStep.TaxRateInHundredthPercent)
{
fprintf(stderr, "Income ");
printHundredths(incomeInHundredths);
fprintf(stderr, " exceeds value range.\nMax permissible : ");
printHundredths(UINT64_MAX / taxStep.TaxRateInHundredthPercent);
exit(2);
}
// taxableMoney * HundredthsPercent is precise
// (and won't overflow, we asserted that above).
// The division is exact to the cent, rounded down (we are a nice tax office).
// The rate is in "centipercent", so we must then divide by 100*100.
// With percent: "money*11/100" with "centipercent": "money*1100/10000".
return (taxedInThisStep * taxStep.TaxRateInHundredthPercent) / 10000;
}
/// <summary>
/// Step through the tax bracket and apply the tax rate to each
/// step. The steps are interval sizes, not absolute values.
/// </summary>
/// <param name="incomeInHundredth">The income in cents or whatever</param>
/// <param name="taxSteps">The first element in an array of tax steps which have
/// an interval size and a rate for that interval.</param>
/// <returns></returns>
uint64_t computeTaxes(uint64_t incomeInHundredth, struct TaxStep* taxSteps)
{
// The function simply calls itself with the remaining money
// and the remaining tax brackets. Because the last interval is
// UINT_MAX, incomeInHundredth <= taxSteps->StepSizeInHundredths
// always triggers for the last interval, stopping the recursion.
return computeTaxesInHundredthsForStep(incomeInHundredth, *taxSteps)
+ ( incomeInHundredth <= taxSteps->StepSizeInHundredths
? 0
: computeTaxes(incomeInHundredth - taxSteps->StepSizeInHundredths, taxSteps+1)
);
}
// A convenience function.
void errExit(const char* msg)
{
fprintf(stderr, msg);
exit(1); // indicates error
}
/// <summary>
/// Communicates the result of a parsing attempt. EOI is "end of information".
/// </summary>
enum ParseDiagE { ParseDiag_ERR, ParseDiag_EOI, ParseDiag_OK };
/// <summary>
/// A 64 return value which also carries an indicator whether
/// the value could be set properly from the input.
/// </summary>
struct ParseResult
{
uint64_t parsedValue;
enum ParseDiagE parseDiag;
};
/// <summary>
/// Factored out the common logic of the two parse methods below.
/// Sets the ret.parseDiag member appropriately, depending on the scanf diagnostic
/// return value (which indicates the number of parsed items and should be 2).
/// If the diag value is OK, combines the two numbers before and after the dot
/// to set ret.parsedValue,
/// </summary>
/// <returns>the result structure</returns>
struct ParseResult MakeParseResult(uint64_t incomeInInUnits, uint64_t IncomeFractionInHundredths, int scanfDiag)
{
struct ParseResult ret = { 0, ParseDiag_OK };
switch (scanfDiag)
{
case EOF:
// typically OK: End of string, or end of file/pipe closed.
ret.parseDiag = ParseDiag_EOI;
break;
case 0:
case 1:
// bad input: scanf should have read 2.
ret.parseDiag = ParseDiag_ERR;
break;
}
if (IncomeFractionInHundredths > 99)
{
// Could be parsed, but too many "cents", e.g. 1.234
ret.parseDiag = ParseDiag_ERR;
}
if (ret.parseDiag == ParseDiag_OK)
{
// only if everything is OK, actually compute anything.
ret.parsedValue = incomeInInUnits * 100 + IncomeFractionInHundredths;
}
return ret;
}
/// <summary>
/// Expects a number in the English float format [0-9]+\.[0-9]+
/// </summary>
/// <returns></returns>
struct ParseResult ParseIncomeInHundredthsFromString(const char* input)
{
uint64_t incomeInInUnits = 0, IncomeFractionInHundredths = 0;
int diag = sscanf(input, "%" SCNu64 ".%" SCNu64, &incomeInInUnits, &IncomeFractionInHundredths);
return MakeParseResult(incomeInInUnits, IncomeFractionInHundredths, diag);
}
/// <summary>
/// Expects a number in the English float format [0-9]+\.[0-9]+
/// Output a prompt only if asked (do not spam sdout for batch runs).
/// </summary>
/// <returns></returns>
struct ParseResult ParseIncomeInHundredthsFromStream(FILE *stream, int prompt)
{
if (prompt)
{
printf("Please input income values in a format like '12345.99 ...'\n");
}
uint64_t incomeInInUnits = 0, IncomeFractionInHundredths = 0;
int diag = fscanf(stream, "%" SCNu64 ".%" SCNu64, &incomeInInUnits, &IncomeFractionInHundredths);
return MakeParseResult(incomeInInUnits, IncomeFractionInHundredths, diag);
}
void PrintTaxBrackets(struct TaxStep *steps)
{
uint64_t overallIncomeInHundredths = 0;
printf("Tax brackets:\n");
while(1)
{
if (steps->StepSizeInHundredths == UINT64_MAX)
{
printf("Above: ");
printHundredths(steps->TaxRateInHundredthPercent);
printf("%%\n");
break;
}
else
{
printHundredths(overallIncomeInHundredths);
printf(" .. ");
printHundredths(overallIncomeInHundredths += steps->StepSizeInHundredths);
printf(": ");
printHundredths(steps->TaxRateInHundredthPercent);
printf("%%\n");
++steps;
}
}
}
int main(int argc, char** argv)
{
// The specification of the tax brackets: A succession of intervals
// with their respective tax rate, in "centipercent" (1120 would be 11.20%).
// The last step **must** be of size UINT64_MAX (i.e., the remaining income),
// that's how the program recognizes it's the last step
struct TaxStep taxSteps[] = { {1000 * 100, 2 * 100}, {2000 * 100, 7 * 100}, {UINT64_MAX, 11 * 100 } };
// If we have command line arguments we should process those.
int ShouldProcessArgv = argc > 1;
// If stdin is a terminal
int inpIsFromTerminal = isatty(fileno(stdin));
// spam stdout only for interactive sessions.
if (!ShouldProcessArgv && inpIsFromTerminal)
{
PrintTaxBrackets(taxSteps);
}
/// Command line argument index. argv[0] is the program name,
/// so we start with index 1 for the first actual argument.
int argi = 1;
// loop through text command line arguments or textual numbers
// from stdin.
do
{
// Iff there are no command line arguments, we check standard input.
// Apart from the input source, the processing is the same.
struct ParseResult res = ShouldProcessArgv
? ParseIncomeInHundredthsFromString(argv[argi])
: ParseIncomeInHundredthsFromStream(stdin, inpIsFromTerminal);
if (res.parseDiag == ParseDiag_ERR)
{
errExit("Input format error\n");
}
else if (res.parseDiag == ParseDiag_EOI)
{
break;
}
printf("Taxes for ");
printHundredths(res.parsedValue);
printf(": ");
printHundredths(computeTaxes(res.parsedValue, taxSteps));
printf("\n");
} while (ShouldProcessArgv ? ++argi < argc : 1);
return 0;
}
评论
float
double
double
%lf
0.0
float
5/2 + 0.5
double x = 5/2;