2010-12-28 10 views

Odpowiedz

2

Oczywistym podejściem byłoby użycie tekstowej reprezentacji liczby jako formatu wymiany.

+0

@mekrizzy gdyż oba systemy mogą konwertować pływaki do iz tekst możesz użyć tekstu jako wspólnego języka. –

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 
} 

zmieniłem kawałek kodu nazywa static void float_to_ibm (int od [], int na [], int n, int endian) powyższy kod może działać poprawnie w komputerze z jest mało endian float number. wartość zwracana to duża liczba endianowa ibm, ale przechowywana w typie int.

+0

To naprawdę uratowało mi życie, chciałbym móc nagrodzić cię 50 punktami reputacji dla was obu, którzy pędzili i Noam M, po prostu nie wiem jak. Uwaga: w moim przypadku musiałem odczytać bajty zwróconej int w odwrotnej kolejności, aby uzyskać wydrukowane wyjście do pliku zakodowanego Windows-1252 (little endian). To było dla SAS XPORT. –

0

Niedawno musiałem zamienić jeden płyn na inny. Wygląda na to, że format XDR używa nieparzystego formatu dla jego spławów. Tak więc podczas konwersji z XDR na standardowe pływaki, ten kod to zrobił.

#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

Korzystanie pierwsza odpowiedź dodałem następujące, które mogą być przydatne w niektórych przypadkach:

///

/// 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; 
     } 
    } 
Powiązane problemy