把一个IEEE754浮点数转换为IBM370浮点数的C#代码
把一个IEEE754浮点数转换为IBM370浮点数的C#代码。
在这个网页上有古老的IBM370浮点格式的说明。
// 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
}
在这段C代码的基础上修改的
/* Assumes sizeof(int) == 4 */
static void float_to_ibm(int from[], int to[], int n, int endian)
/**********************************************************************
float_to_ibm - convert between 32 bit IBM and IEEE floating numbers
***********************************************************************
Input:
from input vector
n number of floats in vectors
endian =0 for little endian machine, =1 for big endian machines Output:
to output vector, can be same as input vector ***********************************************************************
Notes:
Up to 3 bits lost on IEEE -> IBM IBM -> IEEE may overflow or underflow, taken care of by
substituting large number or zero Only integer shifting and masking are used.
***********************************************************************
Credits: CWP: Brian Sumner
***********************************************************************/
{
register int fconv, fmant, i, t; for (i=0;i<n;++i) {
fconv = from[i];
if (fconv) {
fmant = (0x007fffff & fconv) | 0x00800000;
t = (int) ((0x7f800000 & fconv) >> 23) - 126;
while (t & 0x3) { ++t; fmant >>= 1; }
fconv = (0x80000000 & fconv) | (((t>>2) + 64) << 24) | fmant;
}
if(endian==0)
fconv = (fconv<<24) | ((fconv>>24)&0xff) |
((fconv&0xff00)<<8) | ((fconv&0xff0000)>>8); to[i] = fconv;
}
return; }
另外找到的一些C代码放在这里以后备用
#include "ibmieee.h" /*---------------------------------------------------------------------
*
* FILE: ./ibmieee.c
*
*----------------------------------------------------------------------
*
* DESCRIPTION:
* Conversion from IBM to IEEE format
* Byte order is detected and accounted for using
* define constant 'L_ENDIAN'
*
*----------------------------------------------------------------------
* ROUTINES DEFINED IN THIS MODULE:
*----------------------------------------------------------------------
*
*
* Convert IBM to IEEE integer:
*
* ibm_ieee_i( n, ibm, ieee)
* int n;
* int *ibm;
* int *ieee;
*
* Convert IEEE to IBM integer:
*
* ieee_ibm_i( n, ieee, ibm)
* int n;
* int *ieee;
* int *ibm;
*
* Convert IBM to IEEE short floating point:
*
* ibm_ieee_f( n, ibm, ieee)
* int n;
* char *ibm;
* float *ieee;
*
* Convert IEEE to IBM floating point:
*
* ieee_ibm_f( n, ieee, ibm)
* int n;
* float *ieee;
* char *ibm;
*
*---------------------------------------------------------------------*/ void ibm_ieee_i( int n, char *ibm, char *ieee )
/*
Convert from IBM to IEEE integer, possibly in-place
*/
#ifdef L_ENDIAN
{
int j;
char temp; /* Reverse byte order on little endian machines */
for (j=0; j<4*n; j+=4) {
temp=ibm[j];
ieee[j]=ibm[j+3];
ieee[j+3]=temp;
temp=ibm[j+1];
ieee[j+1]=ibm[j+2];
ieee[j+2]=temp;
} #else {
int j; /* Move words if not same location */ if (ibm != ieee)
for (j=0; j<n; j++)
ieee[j] = ibm[j]; #endif /* L_ENDIAN */ return ; } /*********************************************************************/ void ieee_ibm_i( int n, char *ibm, char *ieee )
/*
Convert from IEEE to IBM integer, possibly in-place
*/ #ifdef L_ENDIAN
{
int j;
char temp; /* Reverse byte order on little endian machines */
for (j=0; j<4*n; j+=4) {
temp=ieee[j];
ibm[j]=ieee[j+3];
ibm[j+3]=temp;
temp=ieee[j+1];
ibm[j+1]=ieee[j+2];
ibm[j+2]=temp;
} #else
{
int j; /* Move words if not same location */ if (ibm != ieee)
for (j=0; j<n; j++)
ibm[j] = ieee[j]; #endif /* L_ENDIAN */
return ; } /*---------------------------------------------------------------------
*
* Convert from IBM short real to IEEE short real
*
*
* Bit formats for Big Endian processors (i.e. 68020, SPARC, RS6000):
*
* 0 1 2 3 Byte Offset
* --------------------------------------
* IBM !S! EXP ! MH ! MM ! ML !
* --------------------------------------
* 0 1 7 8 15 16 23 24 31 bit number
*
* 0 1 2 3 Byte Offset
* --------------------------------------
* IEEE !S! EXP ! MH ! MM ! ML !
* --------------------------------------
* 0 1 8 9 15 16 23 24 31 bit number
*
*
* Bit formats for Little Endian processors (i.e. Intel 80x86):
*
* 3 2 1 0 byte offset
* --------------------------------------
* IBM ! ML ! MH ! MH !S! EXP !
* --------------------------------------
* 31 24 23 16 15 8 7 6 0 bit number
*
* 3 2 1 0 byte offset
* --------------------------------------
* IEEE !S! EXP !! MH ! MM ! ML !
* --------------------------------------
* 31 30 23 22 16 15 8 7 0 bit number
*
*
* ML, MM, and MH refer to the low, middle, and high order mantissa
* bytes. S is the sign bit, EXP is the exponent. Bits and bytes
* are numbered in order of increasing address in memory. The fields
* are shown in the order that a Hex constant in C would be used as
* a mask for accessing bits.
*
*
* A floating point number in the IBM format is defined to be:
*
* (sign) 0.(significand) * 16**(exponent-64)
*
* In the IEEE format, a floating point number is:
*
* (sign) 1.(significand) * 2**(exponent-127)
*
* The differences are:
*
* 1. IBM assumes a 0 to left of decimal point,
* IEEE assumes a 1 to left of decimal point.
* Since the IBM format has 1 more bit for the significand,
* they both have the same precision: 24 binary digits.
*
* 2. The base for the exponent is 16 for IBM, 2 for IEEE
*
* 3. The bias for the exponent is 64 for IBM, 127 for IEEE
*
* 4. The exponent is 7 bits for IBM, 8 for IEEE. The exponent
* range is then -64 to +63 for IBM, -127 to +128 for IEEE.
*
* 5. Since the IBM format has base 16, the decimal exponent
* range for IBM is about twice that for IEEE:
* IBM: 0.1H * 16**(-64) to 0.FFFFFFH * 16**(+63)
* = 5.4 * 10**(-79) to 7.2 * 10**(+75)
* IEEE: 1.0H * 2**(-127) to 1.FFFFFFH * 2**(+128)
* = 5.9 * 10**(-39) to 6.8 * 10**(+38)
*
* To convert IBM to IEEE:
*
* 1. Multiply IBM exponent by 4 to convert base from 16 to 2,
* subtract 129 to adjust for difference in bias (16*4-127).
*
* 2. Shift the IBM significand left 1 bit and subtract 1 from
* the exponent. If the significand MSB is still 0, repeat.
*
* 3. If the exponent overflows, set result to +-infinity. If
* it underflows, set to +-zero.
*
* 4. Move the converted sign, significand, and exponent into
* the appropriate fields for the IEEE format.
*
*
* To convert IEEE to IBM:
*
* 1. Get IEEE mantissa (bits 0-22). OR in a 1 in bit 23 to
* account for assumed leading '1'.
*
* 2. Get IEEE exponent. Add 1 to exponent to place the decimal
* point before the '1' in the mantissa. Subtract IEEE bias
* of 127 to yield true base 2 exponent.
*
* 3. Divide IEEE exponent by 4 to convert to base 16 exponent:
* 0.X * 2**Y = 0.X * 16**(Y/4)
* Save remainder from division. If remainder is not zero:
* 0.X * 16**(I+1/4) = 2*(0.X) * 16**I = (1/8)0.X * 16**(I+1)
* 0.X * 16**(I+2/4) = 4*(0.X) * 16**I = (1/4)0.X * 16**(I+1)
* 0.X * 16**(I+3/4) = 8*(0.X) * 16**I = (1/2)0.X * 16**(I+1)
* I.E., add 1 to exponent, shift mantissa right by
* (4 - remainder). Add IBM bias of 64 to exponent.
*
* 4. Move the converted sign, significand, and exponent into
* the appropriate fields for the IBM format.
*
*
*---------------------------------------------------------------------*/ void ibm_ieee_f( int n, VAL *ibm, VAL *ieee ) {
int i,iret;
VAL tmp1,tmp2,temp;
int exp; iret = 0; for (i=0; i<n; i++) { /* Move IBM word to properly aligned temp location */
temp.c[0] = ibm[i].c[0];
temp.c[1] = ibm[i].c[1];
temp.c[2] = ibm[i].c[2];
temp.c[3] = ibm[i].c[3]; /* check for true zero */
if (temp.u == 0) {
ieee[i].c[0] = ieee[i].c[1] = ieee[i].c[2] =
ieee[i].c[3] = '\0';
continue;
}
/* extract mantissa */
#ifdef L_ENDIAN
tmp1.c[0] = temp.c[3];
tmp1.c[1] = temp.c[2];
tmp1.c[2] = temp.c[1];
tmp1.c[3] = '\0';
#else
tmp1.u = temp.u;
tmp1.c[0] = '\0';
#endif /* Extract exponent */
/* remove sign bit, multiply by 4, subtract bias difference */
exp = ((temp.c[0] & 0x7F) << 2 ) - 129; /* Shift mantissa up 1 bit until there is a 1 in the MSB */
while ( (tmp1.u & 0x800000) == 0 ) {
exp--;
tmp1.u = tmp1.u << 1;
};
/* Discard MSB and decrement exponent 1 more */
tmp1.u = tmp1.u & 0x007FFFFF;
exp--; /* Check for exponent overflow or underflow */
if (exp & 0xFF00) {
if (exp < 0)
/* Underflow */
ieee[i].c[0] = ieee[i].c[1] = ieee[i].c[2] =
ieee[i].c[3] = '\0';
else {
/* Overflow */
#ifdef L_ENDIAN
ieee[i].c[3] = 0x7F;
ieee[i].c[2] = 0x80;
ieee[i].c[1] = 0x00;
ieee[i].c[0] = 0x00;
#else
ieee[i].c[0] = 0x7F;
ieee[i].c[1] = 0x80;
ieee[i].c[2] = 0x00;
ieee[i].c[3] = 0x00;
#endif
}
iret = 1;
continue;
} /* Move exponent into proper field and set sign bit */
tmp2.u = 0;
#ifdef L_ENDIAN
tmp2.c[3] = (char)exp;
tmp2.u = tmp2.u >> 1;
if (temp.u & 0x00000080)
tmp2.u = tmp2.u | 0x80000000;
else
tmp2.u = tmp2.u & 0x7fffffff;
#else
tmp2.c[0] = (char)exp;
tmp2.u = tmp2.u >> 1;
tmp2.u = tmp2.u | (temp.u & 0x80000000);
#endif
/* Set output value */
temp.u = tmp1.u | tmp2.u;
ieee[i].c[0] = temp.c[0];
ieee[i].c[1] = temp.c[1];
ieee[i].c[2] = temp.c[2];
ieee[i].c[3] = temp.c[3];
}
return ;
} /*********************************************************************/ void ieee_ibm_f( int n, VAL *ieee, VAL *ibm ) {
int i;
VAL temp,tmp1,tmp2;
int exp,rem; for (i=0; i<n; i++) { /* Move to properly aligned location */
temp.c[0] = ieee[i].c[0];
temp.c[1] = ieee[i].c[1];
temp.c[2] = ieee[i].c[2];
temp.c[3] = ieee[i].c[3];
/* check for true zero */
if (temp.u == 0) {
ibm[i].c[0] = ibm[i].c[1] = ibm[i].c[2] =
ibm[i].c[3] = '\0';
continue;
}
/* extract mantissa, OR in leading '1' */
tmp1.u = (temp.u & 0x007FFFFF) | 0x00800000; /* Extract exponent */
/* remove sign bit, shift up one bit */
tmp2.u = (temp.u & 0x7F800000) << 1;
/* Add 1 for mantissa shift, subtract 127 for IEEE bias */
#ifdef L_ENDIAN
exp = (unsigned)tmp2.c[3] - 126;
#else
exp = (unsigned)tmp2.c[0] - 126;
#endif /* Divide exponent by 4, save remainder, add IBM bias of 64 */
rem = exp & 0x03;
exp = (exp >> 2) + 64;
/* Normalize mantissa by shifting by (4-remainder) */
if (rem) {
tmp1.u = tmp1.u >> (4-rem);
exp = exp + 1;
} /* Move exponent and mantissa bytes into IBM locations */
#ifdef L_ENDIAN
tmp2.u = 0;
tmp2.c[0] = (char)exp;
tmp2.c[1] = tmp1.c[2];
tmp2.c[2] = tmp1.c[1];
tmp2.c[3] = tmp1.c[0];
/* Set sign bit */
if (temp.u & 0x80000000) tmp2.u = tmp2.u | 0x00000080;
#else
tmp2.u = tmp1.u;
tmp2.c[0] = (char)exp;
/* Set sign bit */
if (temp.u & 0x80000000) tmp2.u = tmp2.u | 0x80000000;
#endif /* Set output value */
ibm[i].c[0] = tmp2.c[0];
ibm[i].c[1] = tmp2.c[1];
ibm[i].c[2] = tmp2.c[2];
ibm[i].c[3] = tmp2.c[3];
}
return ;
}
把一个IEEE754浮点数转换为IBM370浮点数的C#代码的更多相关文章
- [SQL]当输入表达式得数为一个有效的整数、浮点数、money 或 decimal 类型,那么 ISNUMERIC 返回 1;否则返回 0
ISNUMERIC ( expression ) 当输入表达式得数为一个有效的整数.浮点数.money 或 :否则返回 .返回值为 确保可以将 expression 转换为上述数字类型中的一种. 注意 ...
- 浮点数转换为人名币读法字符串(JAVA)
/*<java疯狂讲义>浮点数转换为人名币读法字符串这个用例,感觉没有考虑零的情况*/ import java.util.Arrays; public class Num2Rmb { pr ...
- float:浮点型double:双精度实型decimal:数字型单精度浮点数(Single)双精度浮点数(double)
单精度浮点数(Single) 双精度浮点数(double) Decimal为SQL Server.MySql等数据库的一种数据类型,不属于浮点数类型,可以在定义时划定整数部分以及小 ...
- 把一个一维数组转换为in ()
把一个一维数组转换为in()形式. function dbCreateIn($itemList) { if(empty($itemList )){ return " IN ('') &quo ...
- Bean-Query 一个把对象转换为Map的Java工具库
刚开源了一个经过完整測试的Java工具类. 地址例如以下: https://github.com/Jimmy-Shi/bean-query 使用说明例如以下: Bean-query Click Her ...
- 小朋友学C语言(4):单精度浮点数与双精度浮点数
上节课简单介绍了浮点数.计算机程序中的浮点数分为单精度浮点数和双精度浮点数. 单精度和双精度精确的范围不一样. 计算机里的最基本的存储单位用位(bit)来表示.bit只能用来存储0或1. 稍大一点的单 ...
- 如何在一个网站或者一个页面,去书写你的JS代码
// JavaScript Document //如何在一个网站或者一个页面,去书写你的JS代码: //1.js的分层(功能) : jquery(tools) 组件(ui) 应用(app), mvc( ...
- 通过汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的
秦鼎涛 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 实验一 通过汇编一个简单的C程序,分析汇编代码 ...
- 通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的
实验一:通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的 学号:20135114 姓名:王朝宪 注: 原创作品转载请注明出处 <Linux内核分析>MOOC课程http: ...
随机推荐
- ThoughtWorks.QRCode类库
ThoughtWorks.QRCode一个二维码生成类库.
- golang type
参考链接 https://blog.csdn.net/tzs919/article/details/53571632 type是golang中非常重要的关键字,常见的就是定义结构体,但是其功能远不止是 ...
- lr关联-保存数组并调用(转)
LOADRUNNER中的一个关联技巧 众所周知,在LoadRunner中,关联是一个很重要的动作,大多数的脚本在录制完成后并不能直接回放,需要通过一定的关联才能成功回放.关联的技巧有很多,这里 ...
- vmware 已将该虚拟机配置为使用 64 位客户机操作系统。但是,无法执行 64 位操作。
错误提示:已将该虚拟机配置为使用 64 位客户机操作系统.但是,无法执行 64 位操作. 此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态. 如果已在 BIOS/固件设置中禁用 ...
- 如何从 GitHub 上下载单个文件夹?
比如别人把一些资料传到 GitHub 上做分类归档,我怎么才能下载单一分类文件夹? 点击 Raw ,如果是不能预览的文件就会自动下载,如果是文件或者代码什么的,会在浏览器中显示,但可以复制浏览器中链接 ...
- linux下安装jenkins
我们不用离线安装方式 第一步.必须验证java环境 第二步.我们这里使用yum命令进行在线安装,使用service命令进行启动 1.wget -O /etc/yum.repos.d/jenkins.r ...
- Android Apollo MQTT入门
一.Apache Apollo服务器其实是一个消息中转站 下载地址 http://activemq.apache.org/apollo/download.html 服务搭建方式,参看博客Android ...
- [Ispc2009]Let there be rainbows!
Description HY Star是一个处处充满和谐,人民安居乐业的星球,但是HYStar却没有被评上宇宙文明星球,很大程度上是因为星球的形象问题. HY Star由N个国家组成,并且在一些国家之 ...
- 【转】一口气读懂NB-IoT
在过去的一年多,NB-IoT真的可以说是大红大紫.在通信圈里,除了说5G,就是说物联网.如果说物联网,八成就是在说NB-IoT. 在目前5G还没来的情况下,NB-IoT基本上是独领风骚.风光无限. 各 ...
- Android Support Palette使用详解
使用Palette API选择颜色 良好的视觉设计是app成功所必不可少的, 而色彩设计体系是设计的基础构成. Palette包是支持包, 能够从图片中解析出突出的颜色, 从而帮助你创建出视觉迷人的应 ...