VB6 không xuất hiện để làm cho nó dễ dàng để lưu trữ + vô cùng, -infinity và NaN vào đôi vars. Nó sẽ giúp ích nếu nó có thể để tôi có thể so sánh với các giá trị đó trong bối cảnh các số phức. Làm sao?Làm thế nào để bạn nhận được VB6 để khởi tạo đôi với + vô cùng, -infinity và NaN?
Trả lời
Một vài điều khác nhau. Như bạn có thể thấy từ ví dụ của Pax, bạn thực sự chỉ cần tra cứu chuẩn IEEE 754 và sau đó cắm các byte của bạn vào đúng vị trí. Sự thận trọng duy nhất tôi sẽ cung cấp cho bạn là MicroSoft has deprecated RtlMoveMemory do có khả năng tạo ra các vấn đề bảo mật của loại tràn. Như một sự thay thế, bạn có thể thực hiện điều này trong VB "tinh khiết" với một chút ép buộc cẩn thận bằng cách sử dụng User Defined Types và LSet. (Cũng lưu ý rằng có hai loại NaN.)
Option Explicit
Public Enum abIEEE754SpecialValues
abInfinityPos
abInfinityNeg
abNaNQuiet
abNaNSignalling
abDoubleMax
abDoubleMin
End Enum
Private Type TypedDouble
value As Double
End Type
Private Type ByteDouble
value(7) As Byte
End Type
Public Sub Example()
MsgBox GetIEEE754SpecialValue(abDoubleMax)
End Sub
Public Function GetIEEE754SpecialValue(ByVal value As abIEEE754SpecialValues) As Double
Dim dblRtnVal As Double
Select Case value
Case abIEEE754SpecialValues.abInfinityPos
dblRtnVal = BuildDouble(byt6:=240, byt7:=127)
Case abIEEE754SpecialValues.abInfinityNeg
dblRtnVal = BuildDouble(byt6:=240, byt7:=255)
Case abIEEE754SpecialValues.abNaNQuiet
dblRtnVal = BuildDouble(byt6:=255, byt7:=255)
Case abIEEE754SpecialValues.abNaNSignalling
dblRtnVal = BuildDouble(byt6:=248, byt7:=255)
Case abIEEE754SpecialValues.abDoubleMax
dblRtnVal = BuildDouble(255, 255, 255, 255, 255, 255, 239, 127)
Case abIEEE754SpecialValues.abDoubleMin
dblRtnVal = BuildDouble(255, 255, 255, 255, 255, 255, 239, 255)
End Select
GetIEEE754SpecialValue = dblRtnVal
End Function
Public Function BuildDouble(_
Optional byt0 As Byte = 0, _
Optional byt1 As Byte = 0, _
Optional byt2 As Byte = 0, _
Optional byt3 As Byte = 0, _
Optional byt4 As Byte = 0, _
Optional byt5 As Byte = 0, _
Optional byt6 As Byte = 0, _
Optional byt7 As Byte = 0 _
) As Double
Dim bdTmp As ByteDouble, tdRtnVal As TypedDouble
bdTmp.value(0) = byt0
bdTmp.value(1) = byt1
bdTmp.value(2) = byt2
bdTmp.value(3) = byt3
bdTmp.value(4) = byt4
bdTmp.value(5) = byt5
bdTmp.value(6) = byt6
bdTmp.value(7) = byt7
LSet tdRtnVal = bdTmp
BuildDouble = tdRtnVal.value
End Function
Một ngoái mặt lưu ý, bạn cũng có thể nhận NaN theo cách này:
Public Function GetNaN() As Double
On Error Resume Next
GetNaN = 0/0
End Function
This page hiển thị một cách hơi mạo hiểm để thực hiện điều đó. Tôi đã cắt nó xuống để phù hợp với những gì câu hỏi của bạn yêu cầu nhưng chưa được kiểm tra kỹ lưỡng. Hãy cho tôi biết nếu có bất kỳ vấn đề gì. Một điều tôi nhận thấy trên trang web đó là mã họ đã có cho một NaN yên tĩnh là sai, nó sẽ bắt đầu mantissa với 1-bit - họ dường như đã nhận được rằng nhầm lẫn với một tín hiệu NaN.
Public NegInfinity As Double
Public PosInfinity As Double
Public QuietNAN As Double
Private Declare Sub CopyMemoryWrite Lib "kernel32" Alias "RtlMoveMemory" (_
ByVal Destination As Long, source As Any, ByVal Length As Long)
' IEEE754 doubles: '
' seeeeeee eeeemmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm '
' s = sign '
' e = exponent '
' m = mantissa '
' Quiet NaN: s = x, e = all 1s, m = 1xxx... '
' +Inf : s = 0, e = all 1s, m = all 0s. '
' -Inf : s = 1, e = all 1s, m = all 0s. '
Public Sub Init()
Dim ptrToDouble As Long
Dim byteArray(7) As Byte
Dim i As Integer
byteArray(7) = &H7F
For i = 0 To 6
byteArray(i) = &HFF
Next
ptrToDouble = VarPtr(QuietNAN)
CopyMemoryWrite ptrToDouble, byteArray(0), 8
byteArray(7) = &H7F
byteArray(6) = &HF0
For i = 0 To 5
byteArray(i) = 0
Next
ptrToDouble = VarPtr(PosInfinity)
CopyMemoryWrite ptrToDouble, byteArray(0), 8
byteArray(7) = &HFF
byteArray(6) = &HF0
For i = 0 To 5
byteArray(i) = 0
Next
ptrToDouble = VarPtr(NegInfinity)
CopyMemoryWrite ptrToDouble, byteArray(0), 8
End Sub
Về cơ bản nó sử dụng bản sao bộ nhớ kernel cấp để chuyển các mẫu bit từ một mảng byte để được cú đúp. Tuy nhiên, bạn nên nhớ rằng có bit-giá trị có thể đại diện cho QNaN, cụ thể bit dấu có thể là 0 hoặc 1 và tất cả các bit của mantissa khác với giá trị đầu tiên cũng có thể bằng 0 hoặc 1. Điều này có thể làm phức tạp chiến lược của bạn để so sánh trừ khi bạn có thể khám phá nếu VB6 chỉ sử dụng một trong các mẫu bit - nó sẽ không ảnh hưởng đến việc khởi tạo các giá trị đó, giả sử VB6 thực hiện đúng IEE754 gấp đôi.
Vì vậy, bạn đang liên kết đến blog questionner gốc, nơi ông đã đăng một mục với đâm tốt nhất của mình một ngày trước khi đặt câu hỏi? Đủ công bằng, nó thật là vui! – MarkJ
Đó không chỉ là thú vị, nó vui nhộn. Tôi đã không thực sự biết người hỏi là chủ sở hữu của blog đó vào thời điểm đó, nhưng có biệt danh stackoverflow của mình ngay trên blog :-) Tôi đang trong hai suy nghĩ về việc liệu để xóa câu trả lời này hay không. Nếu không có gì khác, nó có thể cung cấp một số giải trí cho người khác. – paxdiablo
Tôi không chắc chắn có nên cười hay xấu hổ hay không. – bugmagnet
Trên thực tế, có một cách đơn giản để có được NHIÊU Infinity, vô cực và Not a Number:
public lfNaN as Double ' or As Single
public lfPosInf as Double
public lfNegInf as Double
on error resume next ' to ignore Run-time error '6': Overflow and '11': Division by zero
lfNaN = 0/0 ' -1.#IND
lfPosInf = 1/0 ' 1.#INF
lfNegInf = -1/0 ' -1.#INF
on error goto 0 ' optional to reset the error handler
+1 Tôi chưa bao giờ biết điều đó trước đây! Có vẻ như bạn cũng có thể nhận NAN bằng cách đánh giá 0/0? Dù sao, Debug.Print nói rằng đó là -1. # IND khác với 1. # INF mà tôi nhận được từ 1/0. Tôi cho rằng đó là NAN. – MarkJ
+1 Điều đó hoàn toàn tuyệt vời –
'Debug.Print -lfNaN' cho' 1. # QNAN', mà tôi giả định là NaN "yên tĩnh" (?). – Andre
- 1. Khi nào sử dụng NaN hoặc +/- Infinity?
- 2. Để vô cùng và trở lại
- 3. Tại sao pow (-infinity, positive integer) + vô cùng?
- 4. Để vô cùng và xa hơn trong VBA
- 5. Làm thế nào để tạo và khởi tạo SAFEARRAY của đôi trong C++ để vượt qua C#
- 6. Làm thế nào để bạn tạo/khởi tạo Javassist ClassPool bên trong một gói OSGi?
- 7. Làm thế nào để có một khung lớn vô cùng?
- 8. Tạo ra vô cùng phức tạp với std :: phức tạp <T> trong C++
- 9. Làm thế nào để tạo và khởi tạo một mảng với mảng khác?
- 10. Làm thế nào để bạn vô hiệu hóa việc nạp/khởi tạo lớp lười trong JVM của Sun?
- 11. Làm thế nào để khởi tạo, khởi tạo và cư trú một mảng trong TypeScript?
- 12. Lỗi với Sci-Kit Tìm hiểu SGD Algo - "Mảng chứa NaN hoặc vô cùng"
- 13. Nhận foreach() và ggplot2 để nhận được cùng
- 14. Làm thế nào để vô hiệu hóa OUTFILE và INFILE?
- 15. Làm thế nào để bạn nhận được SQL để nhận ra WHERE column = NULL?
- 16. Làm thế nào để phát hiện các giá trị Infinity trong Scala?
- 17. Làm cách nào để vô hiệu hóa "Khởi tạo công cụ Java" khi khởi động Eclipse?
- 18. Làm cách nào để kiểm tra xem một số có được đánh giá là vô cùng không?
- 19. Làm thế nào để bạn xác định khi Windows được thực hiện khởi động lại?
- 20. Nhận ngày chỉnh sửa cuối cùng của tệp trong VB6
- 21. Làm thế nào để bytewap một đôi?
- 22. Làm thế nào để khởi tạo biến trống từ kiểu của riêng bạn trong Scala?
- 23. Lưu trữ các giá trị Java Double Infinity và NaN vào cơ sở dữ liệu MS SQL 2008
- 24. Làm thế nào để bạn nhận được dữ liệu yêu cầu với socket.io với node.js và express?
- 25. Làm thế nào để tách một chuỗi và nhận được kết quả cuối cùng trong jQuery?
- 26. Làm thế nào để khởi tạo và khởi tạo một đối tượng động trong cây biểu thức?
- 27. Tại sao infinity = 0x3f3f3f3f?
- 28. vô hướng khởi tạo với niềng răng
- 29. Làm thế nào để bạn dán với vim mà không cần mã được nhận xét?
- 30. Làm thế nào để khởi tạo jsTree sử dụng JSON
Đây là công cụ cực kỳ tuyệt vời. Cảm ơn rất nhiều vì đã chia sẻ nó. – bugmagnet