VBScript Division - автоматически округляет результат до 2 десятичных знаков - PullRequest
2 голосов
/ 08 апреля 2011

Я пытаюсь преобразовать десятичное число в шестнадцатеричное, встроенная шестнадцатеричная функция ограничена 8 символами, поэтому мне приходится писать свою собственную функцию, однако VBScript, кажется, округляет число до 2 десятичных знаков.

Так, например.

106681252129194/16 = 6667578258074.625

проблема в том, что когда я делаю это в VBScript, этот код

strResult = 106681252129194 / 16

результат равен 6667578258074.63,что делает вычисление шестнадцатеричной цифры небольшой проблемой.

Ответы [ 2 ]

1 голос
/ 08 апреля 2011

Вы должны сделать целочисленную операцию деления и остатка. Приглашаем проверить мою попытку ввести число (double <2 ^ 50) для функции ascii: </p>

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 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
0 голосов
/ 10 апреля 2011

Вы превышаете точность, предлагаемую типом Double, т. Е. 8 байтов.

Это не то, что деление автоматически округляет вещи до 2 десятичных знаков;просто ваши 3-и + десятичные разряды некуда идти и поэтому округляются.

Одним из решений является использование типа Decimal, который предлагает 14 байт дискового пространства.

Dim r As Decimal
r = 106681252129194) / 16 ' r = 6667578258074.625

Примечание: выше для VB.В VBA и VBScript тип Decimal доступен только в Variant.Вы не можете напрямую объявить переменную типа Decimal;Вы должны создать Variant, а затем сделать его подтип Decimal, используя функцию CDec:

Dim r
r = CDec(106681252129194) / CDec(16) ' r = 6667578258074.625

Все же хорошо быть осторожным ... Decimal даст вам 28-29значимые цифры, тогда как Double дает вам только 14-15.С другой стороны, Double дает вам гибкость степени 10 между -324 и +308, как в научной нотации, в то время как с Decimal вы застряли с прямой нотацией, без степеней 10.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...