VBScript除法-将结果自动四舍五入到小数点后2位
我正在尝试将十进制数转换为十六进制数,内置的十六进制函数限制为8个字符,因此我必须编写自己的函数,但是VBScript似乎将数字舍入到小数点后2位 比如说 106681252129194/16=6667578258074.625 问题是当我在VBScript中执行此代码时VBScript除法-将结果自动四舍五入到小数点后2位,vbscript,Vbscript,我正在尝试将十进制数转换为十六进制数,内置的十六进制函数限制为8个字符,因此我必须编写自己的函数,但是VBScript似乎将数字舍入到小数点后2位 比如说 106681252129194/16=6667578258074.625 问题是当我在VBScript中执行此代码时 strResult = 106681252129194 / 16 结果是6667578258074.63,这使得计算十六进制数字成为一个小问题。您必须执行整数除数和余数运算。请查看我尝试将数字(双精度
strResult = 106681252129194 / 16
结果是6667578258074.63,这使得计算十六进制数字成为一个小问题。您必须执行整数除数和余数运算。请查看我尝试将数字(双精度<2^50)转换为ascii函数的情况:
Function ntoa( nNum, iBase )
ntoa = "0"
If nNum Then
ntoa = Mid( "-", Sgn( nNum ) + 2 ) + ntoaPos( Abs( nNum ), iBase )
End If
End Function
Function ntoaPos( nNum, iBase )
If nNum >= 1 Then
Dim nD : nD = Fix( nNum / iBase )
Dim nM : nM = nNum - nD * iBase
ntoaPos = ntoaPos( nD, iBase ) _
& Mid( "0123456789ABCDEFGHIJKLMNOPQRSTUV", 1 + nM, 1 )
End If
End Function
Dim r
r = CDec(106681252129194) / CDec(16) ' r = 6667578258074.625
基本测试代码:
Dim aTests : aTests = Array( _
"zero (default: long)", 0 _
, "zero (Byte)" , CByte( 0 ) _
, "min_long" , CLng( -2^31 ) _
, "max_long" , CLng( 2^31-1 ) _
, "min_long - 1" , -2^31-1 _
, "max_long + 1" , 2^31 _
, "max_ulong" , 4294967295 _
, "big" , 2^40 _
, "bigger" , 2^45 _
, "bigger-1" , 2^45-1 _
, "bigger-11" , 2^45-11 _
, "very big" , 2^50 _
)
Dim nTest
For nTest = 0 To UBound( aTests ) Step 2
WScript.Echo "-----", nTest \ 2, aTests( nTest )
Dim nVal : nVal = aTests( nTest + 1 )
WScript.Echo " Type:", TypeName( nVal ), VarType( nVal )
WScript.Echo " Value:", nVal
WScript.Echo " hexxed:", ntoa( nVal, 16 )
WScript.Echo " decced:", ntoa( nVal, 10 )
WScript.Echo " abced:", ntoa( nVal, 32 )
Next
输出:
----- 0 zero (default: long)
Type: Integer 2
Value: 0
hexxed: 0
decced: 0
abced: 0
----- 1 zero (Byte)
Type: Byte 17
Value: 0
hexxed: 0
decced: 0
abced: 0
----- 2 min_long
Type: Long 3
Value: -2147483648
hexxed: -80000000
decced: -2147483648
abced: -2000000
----- 3 max_long
Type: Long 3
Value: 2147483647
hexxed: 7FFFFFFF
decced: 2147483647
abced: 1VVVVVV
----- 4 min_long - 1
Type: Double 5
Value: -2147483649
hexxed: -80000001
decced: -2147483649
abced: -2000001
----- 5 max_long + 1
Type: Double 5
Value: 2147483648
hexxed: 80000000
decced: 2147483648
abced: 2000000
----- 6 max_ulong
Type: Double 5
Value: 4294967295
hexxed: FFFFFFFF
decced: 4294967295
abced: 3VVVVVV
----- 7 big
Type: Double 5
Value: 1099511627776
hexxed: 10000000000
decced: 1099511627776
abced: 100000000
----- 8 bigger
Type: Double 5
Value: 35184372088832
hexxed: 200000000000
decced: 35184372088832
abced: 1000000000
----- 9 bigger-1
Type: Double 5
Value: 35184372088831
hexxed: 1FFFFFFFFFFF
decced: 35184372088831
abced: VVVVVVVVV
----- 10 bigger-11
Type: Double 5
Value: 35184372088821
hexxed: 1FFFFFFFFFF5
decced: 35184372088821
abced: VVVVVVVVL
----- 11 very big
Type: Double 5
Value: 1,12589990684262E+15
hexxed: 4000000000000
decced: 1125899906842624
abced: 10000000000
顺便说一句-您不能使用\:
>> a = 2 ^ 32
>> WScript.Echo a
>> b = a / 2
>> WScript.Echo b
>> c = a \ 2
>> WScript.Echo c
>>
4294967296
2147483648
Error Number: 6
Error Description: Overflow
您超过了类型
Double
提供的精度,即8个字节
除法并不是自动将事物舍入到小数点后2位;只是你的第三位+小数点无处可去,因此被四舍五入
一种解决方案是使用类型Decimal
,它提供14字节的存储空间
Dim r As Decimal
r = 106681252129194) / 16 ' r = 6667578258074.625
注:以上为VB版。在VBA和VBScript中,Decimal
类型只能在变量中访问。不能直接声明类型为Decimal
的变量;您必须创建一个变量
,然后使用CDec
函数使其子类型为Decimal
:
Function ntoa( nNum, iBase )
ntoa = "0"
If nNum Then
ntoa = Mid( "-", Sgn( nNum ) + 2 ) + ntoaPos( Abs( nNum ), iBase )
End If
End Function
Function ntoaPos( nNum, iBase )
If nNum >= 1 Then
Dim nD : nD = Fix( nNum / iBase )
Dim nM : nM = nNum - nD * iBase
ntoaPos = ntoaPos( nD, iBase ) _
& Mid( "0123456789ABCDEFGHIJKLMNOPQRSTUV", 1 + nM, 1 )
End If
End Function
Dim r
r = CDec(106681252129194) / CDec(16) ' r = 6667578258074.625
谨慎还是好的Decimal
将为您提供28-29位有效数字,而Double
仅为您提供14-15位有效数字。另一方面,Double
为您提供了在-324和+308之间的10次方的灵活性,就像在科学记数法中一样,而使用Decimal
时,您只能使用直线记数法,没有10次方 VBScript不支持小数,即使存储在变体中也是如此。CDec
函数不存在,即使您获得一个十进制数(例如,通过ADO从数据库中获得),您也必须将其转换为Double以进行比较或操作。谢谢,稍后将对此进行尝试。您可以使用VBScript的整数除法运算符:x\y,而不是使用Fix(x/y)。除了OP的十六进制问题,在VBS中执行操作和不丢失精度的准则是什么?谢谢,你是怎么解决的?