前段時間參加一個公司的筆試,其中一個題目是實現稅前工資和稅后工資的相應轉化(由稅前求稅后、由稅后求稅前)。題目介紹如下:
下表是2011年9月1日起調整后現行的7級超額累進稅率(原題目中沒有最后一列)
全月應納稅所得額 |
稅率 |
速算扣除數(元) |
全月應納稅額不超過1500元 |
3% |
0 |
全月應納稅額超過1500元至4500元 |
10% |
105 |
全月應納稅額超過4500元至9000元 |
20% |
555 |
全月應納稅額超過9000元至35000元 |
25% |
1005 |
全月應納稅額超過35000元至55000元 |
30% |
2755 |
全月應納稅額超過55000元至80000元 |
35% |
5505 |
全月應納稅額超過80000元 |
45% |
13505 |
這里的稅前工資是指:扣除五險一金后的工資;應納稅所得額是稅前工資超過稅起征點(3500元)的工資;稅后工資是稅前工資去除個人所得稅后的工資。
1.稅前工資求解稅后工資
按照上表中個人所得稅稅率,首先分段求得個人所得稅,然后稅前工資減去稅收即得稅后工資。
例如:稅前工資為10000,應納稅所得額為10000-3500=6500,個人所得稅落在三段內,為1500×3%+(4500-1500)×10%+(6500-4500)×20%=745。稅后工資為10000-745=9255。
float function(float wage) { float taxable = wage - 3500; float tax = 0.0; if (taxable > 0 && taxable <= 1500) { tax = taxable * 0.03; } else if(taxable > 1500 && taxable<= 4500) { tax = (taxable -1500)*0.1 + 1500 * 0.03; } else if(taxable > 4500 && taxable<= 9000) { tax = (taxable -4500)*0.2 + 1500 *0.03 + 3000 *0.1; } else if(taxable > 9000 && taxable<= 35000) { tax = (taxable -9000)*0.25 + 1500 *0.03 + 3000 *0.1 + 4500*0.2; } else if(taxable > 35000 && taxable <= 55000) { tax = (taxable -35000)*0.3 + 1500 *0.03 + 3000 *0.1 + 4500*0.2 + 26000 *0.25; } else if(taxable > 55000 && taxable <= 80000) { tax = (taxable -55000)*0.35 + 1500 *0.03 + 3000 *0.1 + 4500*0.2 + 26000 *0.25 + 25000* 0.3; } else if(taxable > 80000) { tax = (taxable -80000)*0.45 + 1500 *0.03 + 3000 *0.1 + 4500*0.2 + 26000 *0.25 + 25000* 0.3 + 25000 * 0.35; } return wage - tax; }
程序比較簡單,面試官看后說這程序誰都會寫,不是我想要的。當時就凌亂了,回來看了查了很多博客,到現在也沒有很好的實現方法。下面介紹下實際中計算稅后工資的方法,這種方式也只是在計算上簡單些,程序實現和上面的方法基本相同。
為了便於計算,引入了速算扣除數的概念。速算扣除數的計算公式是:
本級速算扣除額=上一級最高所得額×(本級稅率-上一級稅率)+上一級速算扣除數
例如:如某人工資扣除3500元后的應納稅所得額是2200元,則稅款計算方法為:1500×3%+700×10%=115元。個人所得稅的計算,也可以將應納稅所得額直接按對應的稅率來速算,但要扣除一個速算扣除數,否則會多計算稅款。
如某人工資扣除3500元后的應納稅所得額是2200元,2200元對應的稅率是10%,則稅款速算方法為:2200*10%-105=115元。這里的105就是速算扣除數,因為2200元中,有1500元多計算了7%的稅款,需要減去。其它金額的速算扣除數,如表格中最后一列所示。
/* *作者:侯凱 *說明:北京:求稅后工資 *日期:2013-10-19 */ float function2(float wage) { float taxable = wage - 3500;//3500征稅起點 float tax = 0; if(0<taxable&&taxable<=1500) { tax = taxable*0.03; } else if(taxable>1500&&taxable<=4500) { tax = taxable*0.1 - 105; } else if(taxable>4500&&taxable<=9000) { tax = taxable*0.2 - 555; } else if(taxable>9000&&taxable<=35000) { tax = taxable*0.25 - 1005; } else if(taxable>35000&&taxable<=55000) { tax = taxable*0.3 - 2755; } else if(taxable>55000&&taxable<=80000) { tax = taxable*0.35 - 5505; } else if(taxable>80000) { tax = taxable*0.45 - 13505; } return wage - tax; }
程序實現也比較簡單,這樣做就需要首先計算出各段的速算扣除數。其它更好的實現方法,目前沒有找到,大家有什么好的思路,希望不吝指教。
2.稅后工資反推稅前工資
引入速算扣除數后,設稅前工資所處的金額段稅率為taxrate,對應金額段的速算數為quicknum,知:
求解思路:首先根據金額段A的稅率和速算數,由稅后計算得稅前工資,判斷如果稅前工資落在金額段A內,返回即可,否則繼續執行。
float after2wage(float taxwage) { float hold = 3500; float wage; //第一段 wage = taxwage; if(wage<hold){return wage;} //第二段 wage = (taxwage-3500*0.03)/(1-0.03); if(wage>hold&&wage<=hold+1500){return wage;} //第三段 wage = (taxwage-105-3500*0.1)/(1-0.1); if(wage>hold+1500&&wage<=hold+4500){return wage;} //第四段 wage = (taxwage-555-3500*0.2)/(1-0.2); if(wage>hold+4500&&wage<=hold+9000){return wage;} //第五段 wage = (taxwage-1005-3500*0.25)/(1-0.25); if(wage>hold+9000&&wage<=hold+35000){return wage;} //第六段 wage = (taxwage-2755-3500*0.3)/(1-0.3); if(wage>hold+35000&&wage<=hold+55000){return wage;} //第七段 wage = (taxwage-5505-3500*0.35)/(1-0.35); if(wage>hold+55000&&wage<=hold+80000){return wage;} //第八段 wage = (taxwage-13505-3500*0.45)/(1-0.1); if(wage>hold+80000){return wage;} }
3.C++中IO的格式控制
3.1使用控制符控制輸出格式,需要包含頭文件iomanip
控制符 |
作用 |
dec |
設置整數的基數為10 |
hex |
設置整數的基數為16 |
oct |
設置整數的基數為8 |
setbase(n) |
設置整數的基數為n(n只能是16,10,8之一) |
setfill(c) |
設置填充字符c,c可以是字符常量或字符變量 |
setprecision(n) |
設置實數的精度為n位。在以fixed(固定小數位 數)形式和scientific(指數)形式輸出時,n為小數位數。 |
setw(n) |
設置字段寬度為n位。 |
setiosflags(ios::fixed) |
設置浮點數以固定的小數位數顯示。 |
setiosflags(ios::scientific) |
設置浮點數以科學計數法(即指數形式)顯示。 |
setiosflags(ios::left) |
輸出數據左對齊。 |
setiosflags(ios::right) |
輸出數據右對齊。 |
setiosflags(ios::skipws) |
忽略前導的空格。 |
setiosflags(ios::uppercase) |
在以科學計數法輸出E和十六進制輸出字母X時,以大寫表示。 |
setiosflags(ios::showpos) |
輸出正數時,給出“+”號。 |
resetiosflags |
終止已設置的輸出格式狀態,在括號中應指定內容。 |
ios為設置格式狀態的格式標志,還包含其他一些。
3.2用流對象的成員控制輸出格式,只需要iostream即可
流成員函數 |
與之作用相同的控制符 |
作用 |
precision(n) |
setprecision(n) |
設置實 數的精度為n位。 |
width(n) |
setw(n) |
設置字段寬度為n位。 |
fill(c) |
setfill(c) |
設置填充字符c。 |
setf( ) |
setiosflags( ) |
設置輸出格式狀態,括號中應給出格式狀態,內容與控制符setiosflags括號中內容相同。 |
unsetf( ) |
resetiosflags( ) |
終止已設置的輸出格式狀態。 |
流成員函數基本可以實現控制符的全部功能。簡單示例
/* *作者:侯凱 *說明:cout格式控制 *日期:2013-10-19 */ #include<iostream> using namespace std; int main() { cout.width(2); cout.fill('0'); cout.setf(ios::left); cout<<1<<endl;//10 system("Pause"); }