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



原作者:
...