代码之家  ›  专栏  ›  技术社区  ›  rossmcm

将Windows“binary”float读取到ASP JScript变量中

  •  1
  • rossmcm  · 技术社区  · 14 年前

    我需要读取由传统的Windows应用程序生成的文件,它以二进制形式存储实数(8字节的“double”类型),即8字节的压缩数组。我可以读取8字节组,但是如何将它呈现给我的ASP JScript代码,这样我就可以再次获得实数。

    或者换个说法:

    假设文件是由Windows(Delphi)程序生成的:

    Assign (f, 'test.bin') ;
    rewrite (f, 1) ;
    r := 1234.56E78 ;
    BlockWrite (f, r, SizeOf (Double)) ;
    Close (f) ;
    

    检查文件将显示它包含8个字节,即:

    94 0E 4C CA C2 97 AD 53
    

    这是IEEE格式的实数。假设我可以在ASP中读回这8个字节,有没有一种简单的方法可以再次获得实数?

    3 回复  |  直到 13 年前
        1
  •  1
  •   Oren Trutner    14 年前

    BitConverter.ToDouble() .

    在ASP.NET页中,这可能看起来像:

    <%@ Page Language="JScript"
        AutoEventWireup="true"
        CodeBehind="Default.aspx.cs"
        Inherits="WebApplication1._Default" %>
    <%
        var bytes: byte[] = [0x94, 0x0e, 0x4c, 0xca, 0xc2, 0x97, 0xad, 0x53];
        var d = BitConverter.ToDouble(bytes, 0);
        Response.Write(d);
    %>
    

    这将为您提供输出:

    1.2345678E+95
    

    (您可以在 http://babbage.cs.qc.edu/IEEE-754/ )

        2
  •  1
  •   rossmcm    14 年前

    谢谢你的帮助。巴贝奇的东西特别有用。对于这里值得一提的是,我必须编写的代码(除了规范之外,没有对任何东西进行全面测试):

    function ReadFileDouble (Stream)
    { 
    var Bytes0To3 = ReadFileLongword (Stream) ;
    var Bytes4To5 = ReadFileWord (Stream) ;
    var Bytes6To7 = ReadFileWord (Stream) ;
    
    var Mantissa = Bytes0To3 + (Bytes4To5 * 65536 * 65536) + ((Bytes6To7 & 0x0F) * 65536 * 65536 * 65536) ;
    var Fraction = Mantissa / 0x0010000000000000 ;
    var Exponent = ((Bytes6To7 >>> 4) & 0x07FF) ;
    var SignBit  = ((Bytes6To7 & 0x8000) != 0) ;
    if (SignBit)
        {
        Sign = -1 ;
        }
    else
        {
        Sign = +1 ;
        }    
    
    var Bias     = 1023 ;
    
    if (Exponent == 0)
        {
        if (Mantissa == 0)
            {
            return (0.00 * Sign) ;
            }
        else
            {
            return ((Fraction * (Math.pow (2.0, - Bias + 1))) * Sign) ;
            }        
        }
    else if (Exponent == 1023)
        {
        if (Mantissa == 0)
            {
            return (Number.POSITIVE_INFINITY * Sign) ;
            }
        else if (Mantissa < 0x0008000000000000)
            {
            return (Number.NaN * Sign) ;
            }
        else
            {
            return (Number.NaN * Sign) ;
            }        
        }    
    else 
        {
        return ((1.0 + Fraction) * (Math.pow (2.0, Exponent - Bias)) * Sign) ;
        }    
    }
    
        3
  •  0
  •   Alon Gubkin    14 年前

    您可以使用ADO流。它用于读取、写入和管理二进制数据或文本流。

    Dim objStream As ADODB.Stream
    objStream.Type = 1
    objStream.LoadFromFile path
    
    Dim Number : Number = BytesToNumEx(objStream.Read 8, 1, 8, False)
    

    不过,您需要以下功能:

    Function BytesToNumEx(ByteArray(), StartRec, EndRec, UnSigned) 
        Dim i
        Dim lng256 : lng256 = 1
        Dim lngReturn : lngReturn = 0
    
        If EndRec < 1 Then
            EndRec = UBound(ByteArray)
        End If
    
        If StartRec > EndRec Or StartRec < 0 Then
            BytesToNumEx = -1
            Exit Function
        End If
    
        lngReturn = lngReturn + (ByteArray(StartRec))
        For i = (StartRec + 1) To EndRec
            lng256 = lng256 * 256
            If i < EndRec Then
                lngReturn = lngReturn + (ByteArray(i) * lng256)
            Else
                If ByteArray(i) > 127 And UnSigned = False Then
                 lngReturn = (lngReturn + ((ByteArray(i) - 256) * lng256))
                Else
                    lngReturn = lngReturn + (ByteArray(i) * lng256)
                End If
            End If
        Next 
    
        BytesToNumEx = lngReturn
    End Function