others - 在VB6中拆分Double Long loword和Long hiword

149 5

我知道ReadFile函數接受LOWORD as long和HIWORD as long參數,但是,無法將double地址拆分為兩個字。

我嘗試了幾種使用Mod和Fix 的方法,但是最終都溢出錯誤。


LoWord = CLng(dNum Mod CDbl(4294967295)) 'Dont care the number I use, I always get overflow error



或者


LoWord = CLng(FMod(dNum, 4294967295#))


HiWord = CLng(dNum - (FMod(dNum, 4294967295#))) 'tryed different number to see the behaviour, don't care




Public Function FMod(a As Double, b As Double) As Double


 FMod = a - Fix(a / b) * b



 'http://en.wikipedia.org/wiki/Machine_epsilon


 'Unfortunately, this function can only be accurate when `a / b` is outside [-2.22E-16,+2.22E-16]


 'Without this correction, FMod(.66, .06) = 5.55111512312578E-17 when it should be 0


 If FMod >= -2 ^ -52 And FMod <= 2 ^ -52 Then '+/- 2.22E-16


 FMod = 0


 End If


End Function



也許vb6不是最好的選擇,但是現在我已經開始用了它,

當我使用函數時


Call SetFilePointer(hDevice, iStartSec * BytesPerSector, 0, FILE_BEGIN)



我必須指定位元組數,然後乘以512 ,

我還嘗試了這個方法:


Private Type TKK_Dbl


 Value As Double


End Type



Private Type Dbl2Long


 LowVal As Long


 HighVal As Long


End Type



Private D As TKK_Dbl


Private L As Dbl2Long



在函數中。


D.Value = CDbl(iStartSec) * CDbl(BytesPerSector)


LSet L = D


Call SetFilePointer(hDevice, L.LowVal, L.HighVal, FILE_BEGIN)



但這對我並不適用。

时间: 原作者:

106 1

如果你可以保證從文件讀取的扇區號永遠不會大於922,337,203,685,可以直接使用Currency,以獲得相同的二進位表達:


dim sector_number_as_string as string


sector_number_as_string ="B3A73CF8186" ' Read from file; decimal 12345678987654



dim iStartSec as currency


iStartSec = CCur("&h" & sector_number_as_string) / 10000@



'At this point iStartSec = 1234567898.7654



dim offset as currency


offset = iStartSec * 512@



但是,如果值可以大於346DC5D638865,則需要自定義解析器,因為CCur將溢出:


Public Type TKK_Cur


 Value As Currency


End Type



Public Type Cur2Long


 LowVal As Long


 HighVal As Long


End Type



' Returns already scaled value, no need to divide by 10000


Public Function ParseLongHex(ByVal s As String) As Currency


 Dim c As TKK_Cur


 Dim l As Cur2Long



 l.LowVal = CLng("&h" & Right$(s, 8))


 If Len(s) > 8 Then l.HighVal = CLng("&h" & Left$(s, Len(s) - 8))



 LSet c = l


 ParseLongHex = c.Value


End Function




dim sector_number_as_string as string


sector_number_as_string ="B3A73CF8186" ' Read from file; decimal 12345678987654



dim iStartSec as currency


iStartSec = ParseLongHex(sector_number_as_string)



'At this point iStartSec = 1234567898.7654



dim offset as currency


offset = iStartSec * 512@



如果SetFilePointer接受兩個指針的指針,你可以調用它,但是按照值和接受lodword,但是,與Currency一樣:


Private Type TKK_Cur


 Value As Currency


End Type



Private Type Cur2Long


 LowVal As Long


 HighVal As Long


End Type



Private C As TKK_Cur


Private L As Cur2Long




C.value = offset


lset l = c



原作者:
...