前段时间把32为IBM 浮点数如何转化成IEEE浮点数的代码整理完,最近有时间了就把32位IEEE浮点数转化为IBM浮点数的代码整理出来了。供大家参考。
公式转换:
转化思路:
1)、提取符号、指数部分、尾数部分。
2)、进行特定值的转换。
3)、指数部分转换,(IEEE阶码 +130)/4= IBM阶码。
4)、尾数移位处理。因为IEEE 和 IBM 的阶码都是整数。尾数最多右移3次。
5)、转化后的符号。指数、尾数的组装。
private static float IEEEtoIBM(float from)
{
uint fraction;
int exponent;
int sign;
uint ui;
根据情况看是否进行字节转换
//System.Array.Reverse(bb);
// @ 标识符号位
// # 标识阶数位
// * 标识尾数位
//IBM浮点数: SEEEEEEE MMMMMMMM MMMMMMMM MMMMMMMM Value = (-1)^s * M * 16^(E-64)
//IEEE浮点数:SEEEEEEE EMMMMMMM MMMMMMMM MMMMMMMM Value = (-1)^s * (1 + M) * 2^(E-127)
byte[] bb = BitConverter.GetBytes(from);
fraction = System.BitConverter.ToUInt32(bb, 0);
sign = (int)(fraction >> 31); // 获取符号位;
fraction <<= 1; // 左移移出符号位,右侧填0;
exponent = (int)(fraction >> 24); // 获取阶数;
fraction <<= 8; //移出符号位 和 阶数 剩余的部分:尾数部分;
/*
* 特定概念值处理
*
* 如果尾数部分为0,则说明该数是特定值:0或者无穷。
* 当指数=255,说明当前数是无穷大; 对应的IBM无穷大时,指数为127。
* 当指数=0,说明当前数为0; 对应的IBM为0时,指数为0.
*
* IEEE非数字:指数为255,小数部分不为零。
* IBM非数字:指数为127,小数部分最高位为1,其他位为0.
*/
if (fraction == 0) //如果尾数为零 判断是否是 无穷大 或 0
{
if (exponent == 0) //0
goto done;
else if (exponent == 255) //无穷大
{
exponent = 127;
goto done;
}
}
else if (exponent == 255) //判断是否是数字
{
fraction = 0x80000000;
goto done;
}
//执行(M+1)/2;
fraction = (fraction >> 1) | 0x80000000;
//因为IBM 和 IEEE 的指数都是整数
//但是(IEEE阶码 +130)/4= IBM阶码。为了保证IBM 阶码是整数。必须对IBM 尾数进行移位处理。
int remainder = (exponent + 130) % 4; //余数
exponent = (exponent + 130) >> 2; //商
if (remainder > 0)
{
exponent++;
fraction = fraction >> (4-remainder);
}
done:
ui = (uint)((exponent << 24) | (sign << 31));
ui = ui | (fraction >> 8);
bb = System.BitConverter.GetBytes(ui);
return System.BitConverter.ToSingle(bb, 0);
}
IBM浮点数 转化为 IEEE浮点数的代码请参考:点击打开链接