(发票金额)金额换汉语老写字的算法以及代码实现
首先编写一个简单的算法,就是要通过举例来探究其规律,然后把规律变为Code。
列出几个常见的数字,针对数字进行研究。
第一个数 152364.23 : 壹拾伍万贰仟叁佰陆拾肆元贰角叁分
1----壹, 位权-----拾
5----伍, 位权-----万
2----贰, 位权-----仟
3----叁, 位权-----佰
6----陆, 位权-----拾
4----肆, 位权-----元
2----贰,位权-----角
3----叁,位权-----分
依照规律,我们建立一个映射关系。
TCHAR* hzUnit[18]={_T("分"),_T("角"),_T("元"),_T("拾"),_T("佰"),_T("仟"),_T("万"),_T("拾"),_T("佰"),_T("仟"),_T("亿"),_T("拾"),_T("佰"),_T("仟"),_T("万"),_T("拾"),_T("佰"),_T("仟")};
TCHAR* hzNum[10]={_T("零"),_T("壹"),_T("贰"),_T("叁"),_T("肆"),_T("伍"),_T("陆"),_T("柒"),_T("捌"),_T("玖")};
接下来要列举几个含有数字位零的数字:
150326 :壹拾伍万零叁佰贰拾陆元
零仟中的仟给去掉了。这个需要特殊处理。
再举一列
3000025000 : 叁拾亿零贰万伍仟元整
你会发现,hzUnit[2]元,hzUnit[6]万,hzUnit[10]亿,hzUnit[14]万
这几位位权在当前数字是零的前提下还是输出了。而其余的就没有输出。
所以判断当前位权是否为2,4,6,10,14(都是数组下标值,实际代码中使用从1开始)就可以解决这问题。
有小数点的数字是否麻烦,不麻烦只要乘以100,之后就可以了。
C++代码如下:
CString CNumToChineseDlg::ChangeNumToChinese(double num) { CString m_strNum, m_strChinese; int iNum; int flag_zero= 0; m_strNum.Format(_T("%18.0lf"), num*100); //乘以100之后变为CString类型,乘以100是为了最小值为分 m_strNum.TrimLeft(); TCHAR* hzUnit[18]={_T("分"),_T("角"),_T("元"),_T("拾"),_T("佰"),_T("仟"),_T("万"),_T("拾"),_T("佰"),_T("仟"),_T("亿"),_T("拾"),_T("佰"),_T("仟"),_T("万"),_T("拾"),_T("佰"),_T("仟")}; TCHAR* hzNum[10]={_T("零"),_T("壹"),_T("贰"),_T("叁"),_T("肆"),_T("伍"),_T("陆"),_T("柒"),_T("捌"),_T("玖")}; int length = m_strNum.GetLength(); if(num<0 || length>18 || length== 0) return _T(""); for(int i=0; i<length; i++) { iNum = _ttoi(m_strNum.Mid(i, 1)); if(iNum == 0) flag_zero++; else { if(flag_zero>0) m_strChinese += "零"; m_strChinese += hzNum[iNum]; flag_zero = 0; } if(iNum != 0 || length-i == 7 || length-i == 3 || length -i == 11 || length -i == 15 ) m_strChinese += hzUnit[length-1-i]; } if(m_strNum.Right(2) =="00") m_strChinese +="整"; return m_strChinese; }函数的返回值就是翻译成老写字的字符串。