473,394 Members | 1,766 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

C code for converting IBM/370 floating point to IEEE 754?

Does anyone have C code laying around to do this?

I have to read in some binary data files that contains some 4-byte
IBM/370 floating point values. I would like a function to convert
4-byte IBM/370 float values into IEEE 754 'float' values that I can
use directly with any modern C environment (that uses IEEE 754).

I can handle endian conversion myself (the files are stored as big
endian, and I'll process them on a little endian machine), but do not
have code for converting an in-memory float (that is in the correct
endianness for the machine) from 370 to IEEE 754. Any help is
appreciated. Thanks,
--
Benjamin Rutt
Nov 14 '05 #1
2 15798
Benjamin Rutt wrote:
Does anyone have C code laying around to do this?

I have to read in some binary data files that contains some 4-byte
IBM/370 floating point values. I would like a function to convert
4-byte IBM/370 float values into IEEE 754 'float' values that I can
use directly with any modern C environment (that uses IEEE 754).

I can handle endian conversion myself (the files are stored as big
endian, and I'll process them on a little endian machine), but do not
have code for converting an in-memory float (that is in the correct
endianness for the machine) from 370 to IEEE 754. Any help is
appreciated.


This question is probably better suited for a group not focused on
Standard C, but check out
http://nssdcftp.gsfc.nasa.gov/miscel...nts/b46645.txt,
specifically the r4ibmieee and r8ibmieee functions. This probably
isn't very portable, but if it doesn't work on your system you can at
least use the algorithm to write your own routine.

Robert Gamble

Nov 14 '05 #2
Benjamin Rutt <ru**@bmi.osu.edu> wrote:

Does anyone have C code laying around to do this?


/* ibm2ieee - Converts a number from IBM 370 single precision floating
point format to IEEE 754 single precision format. For normalized
numbers, the IBM format has greater range but less precision than the
IEEE format. Numbers within the overlapping range are converted
exactly. Numbers which are too large are converted to IEEE Infinity
with the correct sign. Numbers which are too small are converted to
IEEE denormalized numbers with a potential loss of precision (including
complete loss of precision which results in zero with the correct
sign). When precision is lost, rounding is toward zero (because it's
fast and easy -- if someone really wants round to nearest it shouldn't
be TOO difficult). */

#include <sys/types.h>
#include <netinet/in.h>

void ibm2ieee(void *to, const void *from, int len)
{
register unsigned fr; /* fraction */
register int exp; /* exponent */
register int sgn; /* sign */

for (; len-- > 0; to = (char *)to + 4, from = (char *)from + 4) {
/* split into sign, exponent, and fraction */
fr = ntohl(*(long *)from); /* pick up value */
sgn = fr >> 31; /* save sign */
fr <<= 1; /* shift sign out */
exp = fr >> 25; /* save exponent */
fr <<= 7; /* shift exponent out */

if (fr == 0) { /* short-circuit for zero */
exp = 0;
goto done;
}

/* adjust exponent from base 16 offset 64 radix point before first digit
to base 2 offset 127 radix point after first digit */
/* (exp - 64) * 4 + 127 - 1 == exp * 4 - 256 + 126 == (exp << 2) - 130 */
exp = (exp << 2) - 130;

/* (re)normalize */
while (fr < 0x80000000) { /* 3 times max for normalized input */
--exp;
fr <<= 1;
}

if (exp <= 0) { /* underflow */
if (exp < -24) /* complete underflow - return properly signed zero */
fr = 0;
else /* partial underflow - return denormalized number */
fr >>= -exp;
exp = 0;
} else if (exp >= 255) { /* overflow - return infinity */
fr = 0;
exp = 255;
} else { /* just a plain old number - remove the assumed high bit */
fr <<= 1;
}

done:
/* put the pieces back together and return it */
*(unsigned *)to = (fr >> 9) | (exp << 23) | (sgn << 31);
}
}

/* ieee2ibm - Converts a number from IEEE 754 single precision floating
point format to IBM 370 single precision format. For normalized
numbers, the IBM format has greater range but less precision than the
IEEE format. IEEE Infinity is mapped to the largest representable
IBM 370 number. When precision is lost, rounding is toward zero
(because it's fast and easy -- if someone really wants round to nearest
it shouldn't be TOO difficult). */

void ieee2ibm(void *to, const void *from, int len)
{
register unsigned fr; /* fraction */
register int exp; /* exponent */
register int sgn; /* sign */

for (; len-- > 0; to = (char *)to + 4, from = (char *)from + 4) {
/* split into sign, exponent, and fraction */
fr = *(unsigned *)from; /* pick up value */
sgn = fr >> 31; /* save sign */
fr <<= 1; /* shift sign out */
exp = fr >> 24; /* save exponent */
fr <<= 8; /* shift exponent out */

if (exp == 255) { /* infinity (or NAN) - map to largest */
fr = 0xffffff00;
exp = 0x7f;
goto done;
}
else if (exp > 0) /* add assumed digit */
fr = (fr >> 1) | 0x80000000;
else if (fr == 0) /* short-circuit for zero */
goto done;

/* adjust exponent from base 2 offset 127 radix point after first digit
to base 16 offset 64 radix point before first digit */
exp += 130;
fr >>= -exp & 3;
exp = (exp + 3) >> 2;

/* (re)normalize */
while (fr < 0x10000000) { /* never executed for normalized input */
--exp;
fr <<= 4;
}

done:
/* put the pieces back together and return it */
fr = (fr >> 8) | (exp << 24) | (sgn << 31);
*(unsigned *)to = htonl(fr);
}
}

/* Test harness for IEEE systems */
#ifdef TEST
#define MAX 1000000 /* number of iterations */
#define IBM_EPS 4.7683738e-7 /* worst case error */

#include <float.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

double epsm;

void check(float f1)
{
int exp;
float f2;
double eps;
unsigned ibm1, ibm2;

frexp(f1, &exp);
ieee2ibm(&ibm1, &f1, 1);
ibm2ieee(&f2, &ibm1, 1);
ieee2ibm(&ibm2, &f2, 1);
if (memcmp(&ibm1, &ibm2, sizeof ibm1) != 0)
printf("Error: %08x <=> %08x\n", *(unsigned *)&ibm1, *(unsigned *)&ibm2);
eps = ldexp(fabs(f1 - f2), -exp);
if (eps > epsm) epsm = eps;
if (eps > IBM_EPS)
printf("Error: %.8g != %.8g\n", f1, f2);
}

int main()
{
int i;
float f1;

epsm = 0.0;
for (i = 0; i < MAX; i++) {
f1 = drand48();
check(f1);
check(-f1);
}
printf("Max eps: %g\n", epsm);
return 0;
}

#endif

-Larry Jones

Talk about someone easy to exploit! -- Calvin
Nov 15 '05 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

65
by: Pmb | last post by:
I'm confused as to what the compiler error message I'm getting is refering to. Can someone take a gander and let me know what I did wrong? The program is below. When I compile it I get the...
10
by: Vinny | last post by:
I have a few floating point questions/issues I wish to ask. An answer or discussion would be nice too :) Any links discussion the subject would be nice too.. 1. How do I generate an underflow...
7
by: Vinoth | last post by:
I'm working in an ARM (ARM9) system which does not have Floating point co-processor or Floating point libraries. But it does support long long int (64 bits). Can you provide some link that would...
10
by: Bryan Parkoff | last post by:
The guideline says to use %f in printf() function using the keyword float and double. For example float a = 1.2345; double b = 5.166666667; printf("%.2f\n %f\n", a, b);
2
by: Madhusudhanan Chandrasekaran | last post by:
Hi all: When I try to convert a float variable into string via repr() or str() function, i get the value as is, i.e '0.1e-7' in IEEE 754 format. Instead how can force the created string to...
116
by: Dilip | last post by:
Recently in our code, I ran into a situation where were stuffing a float inside a double. The precision was extended automatically because of that. To make a long story short, this caused...
1
by: gnanapoongothai | last post by:
Hi, Any idea about how to convert floating point to IEEE format. thanxs,
8
by: myfem.analyzer | last post by:
Hi, I saw a line of codes in the "Fast Inverse Square Root" like this: Float InvSqrt(float x) { ....... int i = *(int *) &x; //get bits for floating value ..... x = * (float *) &i; ...
39
by: rembremading | last post by:
Hi all! The following piece of code has (for me) completely unexpected behaviour. (I compile it with gcc-Version 4.0.3) Something goes wrong with the integer to float conversion. Maybe somebody...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.