Visual Basic 2010:最近在我的一個項目中,我的任務是以十六進制讀取幾個數據字段。每個字段有三個字符。所以,這就是我一直在做:將十六進制字符串轉換爲整數
'Read the hex value and convert it to decimal
Dim hexVal as string = "38D"
Dim intVal as integer = Convert.ToInt32(hexVal, 16)
'The integer result gets multiplied by a scaling factor
'(this is set by the manufacturer for each field).
Dim fac as single = 200
Dim final as single = intVal * fac
Debug.Print (final)
這已經除非在這種情況下工作的偉大:hexVal =「FFD」和FAC = 32 .NET給我INTVAL = 4093,最終= 130976。 但是我正在檢查的遺留系統給出了-96。
我有點困惑,但推理它是在十六進制符號。我對原始數據的唯一文檔狀態是:字符按ISO字母5編碼,每個字符使用7位,即不添加奇偶校驗位。三個這樣的字符將包含每個32位字的字段。
我是否將此錯誤地轉換?
附錄:我研究了這些字段的定義,並發現幾乎所有的字符都是正的(或無符號的)。一些可以是負面的或正面的(簽名)。查看遺留代碼,對於每個十六進制字段,它們計算無符號結果和簽名結果。如果該字段預計總是正值,那麼他們使用無符號結果。現在,如果字段預期爲負值或正值,則它們取無符號結果,如果高於最大值,則使用簽名結果,否則使用無符號結果。以下是我迄今爲止從下面的代碼片段:
Dim hexVal As String, res As Single, decCeiling As Single
Dim paddedHex1 As String, intVal1 As Integer = 0, resVal1 As Single = 0
Dim paddedHex2 As String, intVal2 As Integer = 0, resVal2 As Single = 0
Dim IsUnsignedInput As Boolean
hexVal = "FB1" 'Raw hex input (in this case represents temperature in deg C)
res = 0.125 'A resolution factor. Used to scale the decimal to a real-world nummber
decCeiling = 150 'The maximum temperature we can expect is 150 degree Celcius
IsUnsignedInput = False 'Is field unsigned or signed (for temps we can expect negative and positive)
If hexVal.Length > 8 Then
Throw New Exception("Input '" & hexVal & "' exceeds the max length of a raw input. The max is 8 characters.")
EndIf
'This calcualtion assumes an unsigned value (that is, always a positive number)
paddedHex1 = hexVal.ToString.PadLeft(8, CChar("0"))
intVal1 = Convert.ToInt32(paddedHex1, 16)
resVal1 = intVal1 * res
'This assumes a signed value (that is, could be a negative OR positive number.
'Use two's complement to arrive at the result.
paddedHex2 = hexVal.PadLeft(8, CChar("F"))
Dim sb As New StringBuilder(paddedHex2.Length)
For i As Integer = 0 To paddedHex2.Length - 1
Dim hexDigit As Integer = Convert.ToInt32(paddedHex2(i), 16)
sb.Append((15 - hexDigit).ToString("X"))
Next i
Dim inverted As Integer = Convert.ToInt32(sb.ToString, 16)
intVal2 = -(inverted + 1)
resVal2 = intVal2 * res
'Finally, which result do we use as the final decimal? For our example we get
'resVal1 (unsigned)=+502.125
'resVal2 (signed) = -9.875
'Field is signed so is 502.125 > 150? Yes, so use the signed result of -9.875.
If IsUnsignedInput Then
'If unsigned then we always expect a positive value so use straight conversion.
Debug.Print("Result=" & resVal1)
Else
'If signed then we expect a positive OR negative value
If resVal1 > decCeiling Then
'Standard conversion yields a higher number than expected so use two's complement to get number
Debug.Print("Result=" & resVal2)
Else
'Standard conversion yields a number that is in the expected range so use straight conversion to get number
Debug.Print("Result=" & resVal1)
End If
End If
做與傳統系統的所有匹配起來背到後端的比較,但它不與十六進制過去太多的工作,我有點謹慎。我希望對此方法提供進一步的反饋意見。
因此,如果我的目標是創建一個.NET應用程序來完成遺留系統的功能,那麼您會在這裏建議什麼路徑?我應該轉向不同類型的轉換方法嗎? – sinDizzy 2014-09-10 21:07:07
謝謝!老實說,你的第二次編輯我有你的最後一個例程的一半。 Dim c As Char = CChar(hexVal.Substring(0))then dim highBits()As Char = {「8」c,「9」c,「A」c,「B」c,「C」c,「D 「c」,「E」c,「F」c}然後Dim IsNeg As Boolean = highBits.Contains(c)。但你的簡潔得多。 – sinDizzy 2014-09-10 21:54:56
好吧,我正在從我們的遺留系統程序員獲取信息的位。他通常說,可能有負值的字段長度爲4或8個十六進制字符。如果我從命令行轉換使用遺留系統,我得到這個:TOHEX -3 = FFFFFFFD,也是TOHEX 2068 = 00000814.我認爲它的內部例程需要8個字符,例如TODEC FFD = 4093和TODEC 814 = 2068。我得到的例程高於0x814 = -2028。我只是沒有得到我們遺留系統正在做的調整。它是否調整了8個字符?我應該留下填充我的十六進制值來獲得4或8個字符? – sinDizzy 2014-09-10 22:28:30