将 Double 转换为 8 字节数组

发布于 2024-12-10 11:09:35 字数 331 浏览 0 评论 0原文

我想将 Double 变量转换为 8 字节数组,这就是我到目前为止所得到的:

Dim b(0 To 7) As Byte
Dim i As Integer

dim d as double
d = 1            ' for simplicity, I sit the variable "d" to 1

For i = 0 To 7
    Call CopyMemory(b(i), ByVal VarPtr(d) + i, 1)
Next i

' b => [0, 0, 0, 0, 0, 0, 240, 63]

我做错了什么?

I want to convert a Double variable into an 8-bytes array, this is what I've come with so far:

Dim b(0 To 7) As Byte
Dim i As Integer

dim d as double
d = 1            ' for simplicity, I sit the variable "d" to 1

For i = 0 To 7
    Call CopyMemory(b(i), ByVal VarPtr(d) + i, 1)
Next i

' b => [0, 0, 0, 0, 0, 0, 240, 63]

What I'm doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

撧情箌佬 2024-12-17 11:09:35

不要使用循环,使用长度参数:

Option Explicit

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
    ByRef Destination As Any, _
    ByRef Source As Any, _
    ByVal Length As Long)

Sub DblToByte(ByVal D As Double)
    Dim Bytes(LenB(D) - 1) As Byte
    Dim I As Integer
    Dim S As String

    CopyMemory Bytes(0), D, LenB(D)

    For I = 0 To UBound(Bytes)
        S = S & CStr(Bytes(I)) & " "
    Next
    MsgBox S
End Sub

Private Sub Form_Load()
    DblToByte 1
    Unload Me
End Sub

Don't use a loop, use the length argument:

Option Explicit

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
    ByRef Destination As Any, _
    ByRef Source As Any, _
    ByVal Length As Long)

Sub DblToByte(ByVal D As Double)
    Dim Bytes(LenB(D) - 1) As Byte
    Dim I As Integer
    Dim S As String

    CopyMemory Bytes(0), D, LenB(D)

    For I = 0 To UBound(Bytes)
        S = S & CStr(Bytes(I)) & " "
    Next
    MsgBox S
End Sub

Private Sub Form_Load()
    DblToByte 1
    Unload Me
End Sub
诗化ㄋ丶相逢 2024-12-17 11:09:35

您不显示声明语句,但可以针对不同用途对 CopyMemory 进行不同的声明。尝试:

Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
                                                 ByVal pDst As Long, _
                                                 ByVal pSrc As Long, _
                                                 ByVal ByteLen As Long _
                                                 )

You don't show your declare statement, but CopyMemory can be declared differently for different uses of it. Try:

Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
                                                 ByVal pDst As Long, _
                                                 ByVal pSrc As Long, _
                                                 ByVal ByteLen As Long _
                                                 )
人生百味 2024-12-17 11:09:35

我知道我参加这个聚会迟到了,但是我们有一些使用 CopyMemory 的代码,这些代码曾经快如闪电,然后突然停止了。我认为这是由于 Windows Defender 的更改所致。我有一个简单的解决方法。创建两种类型,一种用于保存双精度型,一种用于保存构成双精度型的 8 个字节。然后使用 LSet 函数将二进制数据从一个复制到另一个。它的运行速度比 CopyMemory 快 6000(!)倍。与 VBA 相比,本机 API 调用现在速度慢得令人难以置信,这真是垃圾,但我们就是这样……

Private Type TypeDoubleByte
  b1 As Byte
  b2 As Byte
  b3 As Byte
  b4 As Byte
  b5 As Byte
  b6 As Byte
  b7 As Byte
  b8 As Byte
End Type

Private Type TypeDouble
  d As Double
End Type

Private Sub WriteDouble(bytes() As Byte, ByRef pos As Long, val As Double)

  Dim t As TypeDoubleByte
  Dim z As TypeDouble

  z.d = val
  LSet t = z

  bytes(pos + 0) = t.b1
  bytes(pos + 1) = t.b2
  bytes(pos + 2) = t.b3
  bytes(pos + 3) = t.b4
  bytes(pos + 4) = t.b5
  bytes(pos + 5) = t.b6
  bytes(pos + 6) = t.b7
  bytes(pos + 7) = t.b8

  pos = pos + 8

End Sub

I know I'm late to this party, but we've had some code using CopyMemory that used to be lightening fast, then suddenly it has ground to a halt. I believe this to be due to changes with Windows Defender. I have a simple work around. Create two types, one to hold a double, one to hold the 8 bytes that make up a double. Then use the LSet function to copy the binary data from one to the other. It runs 6000(!) times faster than CopyMemory. Pretty rubbish that a native API call is now incredibly slow compared to VBA, but there we are...

Private Type TypeDoubleByte
  b1 As Byte
  b2 As Byte
  b3 As Byte
  b4 As Byte
  b5 As Byte
  b6 As Byte
  b7 As Byte
  b8 As Byte
End Type

Private Type TypeDouble
  d As Double
End Type

Private Sub WriteDouble(bytes() As Byte, ByRef pos As Long, val As Double)

  Dim t As TypeDoubleByte
  Dim z As TypeDouble

  z.d = val
  LSet t = z

  bytes(pos + 0) = t.b1
  bytes(pos + 1) = t.b2
  bytes(pos + 2) = t.b3
  bytes(pos + 3) = t.b4
  bytes(pos + 4) = t.b5
  bytes(pos + 5) = t.b6
  bytes(pos + 6) = t.b7
  bytes(pos + 7) = t.b8

  pos = pos + 8

End Sub
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文