2010-12-28 27 views

Trả lời

2

Cách tiếp cận rõ ràng là sử dụng biểu diễn văn bản của số làm định dạng trao đổi.

+0

@mekrizzy vì cả hai hệ thống có thể chuyển đổi nổi đến và đi từ văn bản, bạn có thể sử dụng văn bản làm ngôn ngữ chung của mình. –

3
// http://en.wikipedia.org/wiki/IBM_Floating_Point_Architecture 
// float2ibm(-118.625F) == 0xC276A000 
// 1 100 0010 0111 0110 1010 0000 0000 0000 
// IBM/370 single precision, 4 bytes 
// xxxx.xxxx xxxx.xxxx xxxx.xxxx xxxx.xxxx 
// s|-exp--| |--------fraction-----------| 
// (7)   (24) 
// value = (-1)**s * 16**(e - 64) * .f range = 5E-79 ... 7E+75 
static int float2ibm(float from) 
{ 
    byte[] bytes = BitConverter.GetBytes(from); 
    int fconv = (bytes[3] << 24) | (bytes[2] << 16) | (bytes[1] << 8)| bytes[0]; 

    if (fconv == 0) return 0; 
    int fmant = (0x007fffff & fconv) | 0x00800000; 
    int t = (int)((0x7f800000 & fconv) >> 23) - 126; 
    while (0 != (t & 0x3)) { ++t; fmant >>= 1; } 
    fconv = (int)(0x80000000 & fconv) | (((t >> 2) + 64) << 24) | fmant; 
    return fconv; // big endian order 
} 

tôi đã thay đổi một đoạn mã gọi là static void float_to_ibm (int từ [], int tới [], int n, int endian) mã trên có thể được chạy một cách chính xác trong PC từ rất ít số float cuối. giá trị trả về là số lớn của số float ibm cuối nhưng được lưu trữ trong loại int.

+0

Điều này thực sự đã cứu mạng tôi, tôi ước tôi có thể thưởng cho bạn 50 điểm danh tiếng cho cả hai bạn tăng tốc và Noam M, tôi chỉ không tìm ra cách. Một thông báo: trong trường hợp của tôi, tôi đã phải đọc các byte của int được trả về theo thứ tự ngược lại để có được đầu ra có thể in ra tệp windows-1252 được mã hóa (ít endian). Đó là cho SAS XPORT. –

0

Gần đây tôi đã chuyển đổi một phao khác. Có vẻ như định dạng XDR sử dụng định dạng lẻ cho các phao của nó. Vì vậy, khi chuyển đổi từ XDR sang float nổi, mã này đã làm nó.

#include <rpc/rpc.h> 

// Read in XDR float array, copy to standard float array 
// out array needs to be allocated before the function call 

bool convertFromXdrFloatArray(float *in, float *out, long size) 
{ 
    XDR xdrs; 
    xdrmem_create(&xdrs,(char *)in, size*sizeof(float), XDR_DECODE); 

    for(int i = 0; i < size; i++) 
    { 
     if(!xdr_float(&xdrs, out++)) { 
      fprintf(stderr,"%s:%d:ERROR:xdr_float\n",__FILE__,__LINE__); 
      exit(1); 
     } 
    } 
    xdr_destroy(&xdrs); 

    return true; 
} 
0

Sử dụng câu trả lời đầu tiên tôi thêm những điều sau đây có thể hữu ích trong một số trường hợp:

///

/// Converts an IEEE floating number to its string representation (4 or 8 ascii codes). 
    /// Useful for SAS XPORT files format. 
    /// </summary> 
    /// <param name="from_">IEEE number</param> 
    /// <param name="padTo8_">When true, output is 8 chars rather than 4</param> 
    /// <returns>Printable string according to hardware's endianness</returns> 
    public static string Float2IbmAsAsciiCodes(float from_, bool padTo8_ = true) 
    { 
     StringBuilder sb = new StringBuilder(); 
     string s; 
     byte[] bytes = BitConverter.GetBytes(Float2Ibm(from_)); // big endian order 

     if (BitConverter.IsLittleEndian) 
     { 
      // Revert bytes order 
      for (int i = 3; i > -1; i--) 
       sb.Append(Convert.ToChar(bytes[i])); 
      s = sb.ToString(); 
      if (padTo8_) 
       s = s.PadRight(8, '\0'); 
      return s; 
     } 
     else 
     { 
      for (int i = 0; i < 8; i++) 
       sb.Append(Convert.ToChar(bytes[i])); 
      s = sb.ToString(); 
      if (padTo8_) 
       s = s.PadRight(8, '\0'); 
      return s; 
     } 
    } 
Các vấn đề liên quan