如何获取无四舍五入整数?VB数值转文本代码舍入异常排查
问题根源与解决方案
问题出在哪?
- 判断与计算脱节:你仅在
Select Case的条件中用Math.Truncate(n)截断了数值,但所有Case块内的计算(比如n \ 10、n Mod 10、数组索引)依然使用原始的Decimal值98.8,而非截断后的整数98。 - VB.NET的Decimal转换规则:
- 对Decimal使用
\(整数除法)时,会先将数值四舍五入为最接近的整数再执行除法。例如98.8 \ 10会先把98.8四舍五入成99,再除以10得到9,对应数组里的"Ninety"。 - 当Decimal值作为数组索引时,VB.NET会自动将其转为Integer,这个转换过程也是四舍五入的。比如调用
NumberToText(8.8)时,arr(n-1)里的n-1=7.8会被转成整数8,对应数组里的"Nine"。
- 对Decimal使用
两者叠加就导致你得到了"Ninety Nine"的结果。
解决方法
在进入Select Case前,先把截断后的整数存为变量,后续所有计算都用这个变量,彻底规避Decimal转换的四舍五入:
Dim truncatedN As Integer = CInt(Math.Truncate(n)) Select Case truncatedN Case 0 Return "" Case 1 To 19 Dim arr() As String = {"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"} Return arr(truncatedN - 1) & " " Case 20 To 99 Dim arr() As String = {"Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"} Return arr(truncatedN \ 10 - 2) & " " & NumberToText(truncatedN Mod 10) Case 100 To 199 Return "One Hundred " & NumberToText(truncatedN Mod 100) Case 200 To 999 Return NumberToText(truncatedN \ 100) & " Hundred " & NumberToText(truncatedN Mod 100) Case 1000 To 1999 Return "One Thousand " & NumberToText(truncatedN Mod 1000) Case 2000 To 999999 Return NumberToText(truncatedN \ 1000) & " Thousand " & NumberToText(truncatedN Mod 1000) Case 1000000 To 1999999 Return "One Million " & NumberToText(truncatedN Mod 1000000) Case 1000000 To 999999999 Return NumberToText(truncatedN \ 1000000) & " Million " & NumberToText(truncatedN Mod 1000000) Case 1000000000 To 1999999999 Return "One Billion " & NumberToText(truncatedN Mod 1000000000) Case Else Return NumberToText(truncatedN \ 1000000000) & " Billion " _ & NumberToText(truncatedN Mod 1000000000) End Select
关键改动
- 提前计算
truncatedN存储截断后的整数,确保所有逻辑都基于无小数的整数值 - 替换所有原始
n的引用为truncatedN,消除Decimal转换时的四舍五入行为
内容的提问来源于stack exchange,提问作者skidl0ck
相关产品推荐
相关产品推荐

