从IBM浮点转换为IEEE浮点标准和反向Versa In C#?

正在为我们正在使用的旧系统寻找IEEE浮点数到IBM浮点格式的方法。

我们可以在C#中使用通用公式吗?

// 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 } 

我更改了一段名为static void float_to_ibm(int from [],int to [],int n,int endian)的代码,上面的代码可以在PC上正确运行是小端的浮点数。 返回值是big endian ibm float number但存储在int类型中。

一种显而易见的方法是使用数字的文本表示作为交换格式。

我最近不得不将一个浮动转换为另一个。 看起来XDR格式的浮点数使用奇数格式。 因此,当从XDR转换为标准浮点数时,此代码就可以实现。

 #include  // 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; } 

使用第一个答案我添加了以下可能在某些情况下有用的内容:

///

  /// Converts an IEEE floating number to its string representation (4 or 8 ascii codes). /// Useful for SAS XPORT files format. ///  /// IEEE number /// When true, output is 8 chars rather than 4 /// Printable string according to hardware's endianness 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; } }