473,893 Members | 1,885 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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 15882
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.e du> 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
4104
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 following error ______________________________ Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland d:\temp\complex\temp.cpp: Error E2333 d:\temp\complex\temp.cpp 73: Class member 'Complex::conjugate(Complex)' declared outside its class Error...
10
6726
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 exception for testing purposes? 2. What is the fastest wat to suppress floating point exceptions? Take the following situation as example. float x = 1.0e38, //max float value
7
3399
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 discuss about ways to emulate floating point calculations with just long int or long long int. For eg., if i've a formula X=(1-b)*Y + b*Z in floating point domain, i can calculate X with just long ints (but, some data may be lost in final division;...
10
18787
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
3463
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 represent the floating point in non-scientific fashion (non IEEE 754 format)? i.e something like 0.000000001 Thanks in advance for your help.
116
36061
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 problems elsewhere in another part of the system where that figure was used for some calculation and some eventual truncation led to the system going haywire. So my question is, given this code: int main() { float f = 59.89F;
1
2522
by: gnanapoongothai | last post by:
Hi, Any idea about how to convert floating point to IEEE format. thanxs,
8
3179
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; //convert bit back to float
39
3594
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 out there understands what happens. Essentially, when I subtract the (double) function value GRID_POINT(2) from a variable which has been assigned the same value before this gives a non-zero result and I really do not understand why.
0
9987
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9832
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
11245
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10840
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10929
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10469
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
8025
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5859
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
4684
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

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.