Use Ashok's IEEE-float-to-long code as the basis for
IEEE-float-to-native-float code, and use that as the basis for IEEE-double-to-native-double code. Use that code on VAXes. Eliminate "ieee-float.h", as we no longer use it; instead, we use the tvbuff routines for extracting IEEE floating-point numbers. svn path=/trunk/; revision=5243
This commit is contained in:
parent
6c12522f42
commit
7d96eec76b
|
@ -1,7 +1,7 @@
|
|||
# Makefile.am
|
||||
# Automake file for Ethereal
|
||||
#
|
||||
# $Id: Makefile.am,v 1.422 2002/04/18 00:29:16 guy Exp $
|
||||
# $Id: Makefile.am,v 1.423 2002/04/24 21:19:37 guy Exp $
|
||||
#
|
||||
# Ethereal - Network traffic analyzer
|
||||
# By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -841,7 +841,6 @@ EXTRA_DIST = \
|
|||
getopt.c \
|
||||
getopt.h \
|
||||
idl2eth.sh \
|
||||
ieee-float.h \
|
||||
image/Makefile.nmake \
|
||||
image/README.image \
|
||||
image/clist_ascend.xpm \
|
||||
|
|
199
epan/tvbuff.c
199
epan/tvbuff.c
|
@ -9,10 +9,13 @@
|
|||
* the data of a backing tvbuff, or can be a composite of
|
||||
* other tvbuffs.
|
||||
*
|
||||
* $Id: tvbuff.c,v 1.32 2002/04/12 23:25:24 guy Exp $
|
||||
* $Id: tvbuff.c,v 1.33 2002/04/24 21:19:38 guy Exp $
|
||||
*
|
||||
* Copyright (c) 2000 by Gilbert Ramirez <gram@alumni.rice.edu>
|
||||
*
|
||||
* Code to convert IEEE floating point formats to native floating point
|
||||
* derived from code Copyright (c) Ashok Narayanan, 2000
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
* Copyright 1998 Gerald Combs
|
||||
|
@ -1005,6 +1008,152 @@ tvb_get_ntohl(tvbuff_t *tvb, gint offset)
|
|||
return pntohl(ptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Stuff for IEEE float handling on platforms that don't have IEEE
|
||||
* format as the native floating-point format.
|
||||
*
|
||||
* For now, we treat only the VAX as such a platform.
|
||||
*
|
||||
* XXX - other non-IEEE boxes that can run UNIX include some Crays,
|
||||
* and possibly other machines.
|
||||
*
|
||||
* It appears that the official Linux port to System/390 and
|
||||
* zArchitecture uses IEEE format floating point (not a
|
||||
* huge surprise).
|
||||
*
|
||||
* I don't know whether there are any other machines that
|
||||
* could run Ethereal and that don't use IEEE format.
|
||||
* As far as I know, all of the main commercial microprocessor
|
||||
* families on which OSes that support Ethereal can run
|
||||
* use IEEE format (x86, 68k, SPARC, MIPS, PA-RISC, Alpha,
|
||||
* IA-64, and so on).
|
||||
*/
|
||||
|
||||
#if defined(vax)
|
||||
|
||||
#include <math.h>
|
||||
|
||||
/*
|
||||
* Single-precision.
|
||||
*/
|
||||
#define IEEE_SP_NUMBER_WIDTH 32 /* bits in number */
|
||||
#define IEEE_SP_EXP_WIDTH 8 /* bits in exponent */
|
||||
#define IEEE_SP_MANTISSA_WIDTH 23 /* IEEE_SP_NUMBER_WIDTH - 1 - IEEE_SP_EXP_WIDTH */
|
||||
|
||||
#define IEEE_SP_SIGN_MASK 0x80000000
|
||||
#define IEEE_SP_EXPONENT_MASK 0x7F800000
|
||||
#define IEEE_SP_MANTISSA_MASK 0x007FFFFF
|
||||
#define IEEE_SP_INFINITY IEEE_SP_EXPONENT_MASK
|
||||
|
||||
#define IEEE_SP_IMPLIED_BIT (1 << IEEE_SP_MANTISSA_WIDTH)
|
||||
#define IEEE_SP_INFINITE ((1 << IEEE_SP_EXP_WIDTH) - 1)
|
||||
#define IEEE_SP_BIAS ((1 << (IEEE_SP_EXP_WIDTH - 1)) - 1)
|
||||
|
||||
static int
|
||||
ieee_float_is_zero(guint32 w)
|
||||
{
|
||||
return ((w & ~IEEE_SP_SIGN_MASK) == 0);
|
||||
}
|
||||
|
||||
static float
|
||||
get_ieee_float(guint32 w)
|
||||
{
|
||||
long sign;
|
||||
long exponent;
|
||||
long mantissa;
|
||||
|
||||
sign = w & IEEE_SP_SIGN_MASK;
|
||||
exponent = w & IEEE_SP_EXPONENT_MASK;
|
||||
mantissa = w & IEEE_SP_MANTISSA_MASK;
|
||||
|
||||
if (ieee_float_is_zero(w)) {
|
||||
/* number is zero, unnormalized, or not-a-number */
|
||||
return 0.0;
|
||||
}
|
||||
#if 0
|
||||
/*
|
||||
* XXX - how to handle this?
|
||||
*/
|
||||
if (IEEE_SP_INFINITY == exponent) {
|
||||
/*
|
||||
* number is positive or negative infinity, or a special value
|
||||
*/
|
||||
return (sign? MINUS_INFINITY: PLUS_INFINITY);
|
||||
}
|
||||
#endif
|
||||
|
||||
exponent = ((exponent >> IEEE_SP_MANTISSA_WIDTH) - IEEE_SP_BIAS) -
|
||||
IEEE_SP_MANTISSA_WIDTH;
|
||||
mantissa |= IEEE_SP_IMPLIED_BIT;
|
||||
|
||||
if (sign)
|
||||
return -mantissa * pow(2, exponent);
|
||||
else
|
||||
return mantissa * pow(2, exponent);
|
||||
}
|
||||
|
||||
/*
|
||||
* Double-precision.
|
||||
* We assume that if you don't have IEEE floating-point, you have a
|
||||
* compiler that understands 64-bit integral quantities.
|
||||
*/
|
||||
#define IEEE_DP_NUMBER_WIDTH 64 /* bits in number */
|
||||
#define IEEE_DP_EXP_WIDTH 11 /* bits in exponent */
|
||||
#define IEEE_DP_MANTISSA_WIDTH 52 /* IEEE_DP_NUMBER_WIDTH - 1 - IEEE_DP_EXP_WIDTH */
|
||||
|
||||
#define IEEE_DP_SIGN_MASK 0x8000000000000000LL
|
||||
#define IEEE_DP_EXPONENT_MASK 0x7FF0000000000000LL
|
||||
#define IEEE_DP_MANTISSA_MASK 0x000FFFFFFFFFFFFFLL
|
||||
#define IEEE_DP_INFINITY IEEE_DP_EXPONENT_MASK
|
||||
|
||||
#define IEEE_DP_IMPLIED_BIT (1LL << IEEE_DP_MANTISSA_WIDTH)
|
||||
#define IEEE_DP_INFINITE ((1 << IEEE_DP_EXP_WIDTH) - 1)
|
||||
#define IEEE_DP_BIAS ((1 << (IEEE_DP_EXP_WIDTH - 1)) - 1)
|
||||
|
||||
static int
|
||||
ieee_double_is_zero(guint64 w)
|
||||
{
|
||||
return ((w & ~IEEE_SP_SIGN_MASK) == 0);
|
||||
}
|
||||
|
||||
static double
|
||||
get_ieee_double(guint64 w)
|
||||
{
|
||||
gint64 sign;
|
||||
gint64 exponent;
|
||||
gint64 mantissa;
|
||||
|
||||
sign = w & IEEE_DP_SIGN_MASK;
|
||||
exponent = w & IEEE_DP_EXPONENT_MASK;
|
||||
mantissa = w & IEEE_DP_MANTISSA_MASK;
|
||||
|
||||
if (ieee_double_is_zero(w)) {
|
||||
/* number is zero, unnormalized, or not-a-number */
|
||||
return 0.0;
|
||||
}
|
||||
#if 0
|
||||
/*
|
||||
* XXX - how to handle this?
|
||||
*/
|
||||
if (IEEE_DP_INFINITY == exponent) {
|
||||
/*
|
||||
* number is positive or negative infinity, or a special value
|
||||
*/
|
||||
return (sign? MINUS_INFINITY: PLUS_INFINITY);
|
||||
}
|
||||
#endif
|
||||
|
||||
exponent = ((exponent >> IEEE_DP_MANTISSA_WIDTH) - IEEE_DP_BIAS) -
|
||||
IEEE_DP_MANTISSA_WIDTH;
|
||||
mantissa |= IEEE_DP_IMPLIED_BIT;
|
||||
|
||||
if (sign)
|
||||
return -mantissa * pow(2, exponent);
|
||||
else
|
||||
return mantissa * pow(2, exponent);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Fetches an IEEE single-precision floating-point number, in
|
||||
* big-endian form, and returns a "float".
|
||||
|
@ -1016,23 +1165,8 @@ tvb_get_ntohl(tvbuff_t *tvb, gint offset)
|
|||
float
|
||||
tvb_get_ntohieee_float(tvbuff_t *tvb, int offset)
|
||||
{
|
||||
/*
|
||||
* XXX - other non-IEEE boxes that can run UNIX include some
|
||||
* Crays, and possibly other machines.
|
||||
*
|
||||
* It appears that the official Linux port to System/390 and
|
||||
* zArchitecture uses IEEE format floating point (not a
|
||||
* huge surprise).
|
||||
*
|
||||
* I don't know whether there are any other machines that
|
||||
* could run Ethereal and that don't use IEEE format.
|
||||
* As far as I know, all of the main commercial microprocessor
|
||||
* families on which OSes that support Ethereal can run
|
||||
* use IEEE format (x86, 68k, SPARC, MIPS, PA-RISC, Alpha,
|
||||
* IA-64, and so on).
|
||||
*/
|
||||
#if defined(vax)
|
||||
#error "Sorry, you'll have to write code to translate to VAX format"
|
||||
return get_ieee_float(tvb_get_ntohl(tvb, offset));
|
||||
#else
|
||||
union {
|
||||
float f;
|
||||
|
@ -1052,12 +1186,17 @@ double
|
|||
tvb_get_ntohieee_double(tvbuff_t *tvb, int offset)
|
||||
{
|
||||
#if defined(vax)
|
||||
#error "Sorry, you'll have to write code to translate to VAX format"
|
||||
union {
|
||||
double d;
|
||||
guint32 w[2];
|
||||
guint64 dw;
|
||||
} ieee_fp_union;
|
||||
#else
|
||||
union {
|
||||
double d;
|
||||
guint32 w[2];
|
||||
} ieee_fp_union;
|
||||
#endif
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
ieee_fp_union.w[0] = tvb_get_ntohl(tvb, offset);
|
||||
|
@ -1066,6 +1205,9 @@ tvb_get_ntohieee_double(tvbuff_t *tvb, int offset)
|
|||
ieee_fp_union.w[0] = tvb_get_ntohl(tvb, offset+4);
|
||||
ieee_fp_union.w[1] = tvb_get_ntohl(tvb, offset);
|
||||
#endif
|
||||
#if defined(vax)
|
||||
return get_ieee_double(dw);
|
||||
#else
|
||||
return ieee_fp_union.d;
|
||||
#endif
|
||||
}
|
||||
|
@ -1108,17 +1250,8 @@ tvb_get_letohl(tvbuff_t *tvb, gint offset)
|
|||
float
|
||||
tvb_get_letohieee_float(tvbuff_t *tvb, int offset)
|
||||
{
|
||||
/*
|
||||
* XXX - other non-IEEE boxes that can run UNIX include Crays
|
||||
* and System/3x0 and zArchitecture, although later S/390
|
||||
* and zArchitecture machines also support IEEE floating
|
||||
* point; I don't know what the compilers used by Linux
|
||||
* for S/390 and zArchitecture use - they might have chosen
|
||||
* to support only machines with IEEE format, and used IEEE
|
||||
* format to avoid portability headaches.
|
||||
*/
|
||||
#if defined(vax)
|
||||
#error "Sorry, you'll have to write code to translate to VAX format"
|
||||
return get_ieee_float(tvb_get_letohl(tvb, offset));
|
||||
#else
|
||||
union {
|
||||
float f;
|
||||
|
@ -1138,12 +1271,17 @@ double
|
|||
tvb_get_letohieee_double(tvbuff_t *tvb, int offset)
|
||||
{
|
||||
#if defined(vax)
|
||||
#error "Sorry, you'll have to write code to translate to VAX format"
|
||||
union {
|
||||
double d;
|
||||
guint32 w[2];
|
||||
guint64 dw;
|
||||
} ieee_fp_union;
|
||||
#else
|
||||
union {
|
||||
double d;
|
||||
guint32 w[2];
|
||||
} ieee_fp_union;
|
||||
#endif
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
ieee_fp_union.w[0] = tvb_get_letohl(tvb, offset+4);
|
||||
|
@ -1152,6 +1290,9 @@ tvb_get_letohieee_double(tvbuff_t *tvb, int offset)
|
|||
ieee_fp_union.w[0] = tvb_get_letohl(tvb, offset);
|
||||
ieee_fp_union.w[1] = tvb_get_letohl(tvb, offset+4);
|
||||
#endif
|
||||
#if defined(vax)
|
||||
return get_ieee_double(dw);
|
||||
#else
|
||||
return ieee_fp_union.d;
|
||||
#endif
|
||||
}
|
||||
|
|
84
ieee-float.h
84
ieee-float.h
|
@ -1,84 +0,0 @@
|
|||
/**********************************************************************
|
||||
*
|
||||
* ieee-float.h
|
||||
*
|
||||
* Implements simple stuff to convert from IEEE float types
|
||||
* to 32-bit longs
|
||||
*
|
||||
* (C) Ashok Narayanan, 2000
|
||||
*
|
||||
* $Id: ieee-float.h,v 1.2 2001/02/04 08:21:35 guy Exp $
|
||||
*
|
||||
* For license details, see the COPYING file with this distribution
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef IEEE_FLOAT_H
|
||||
#define IEEE_FLOAT_H
|
||||
|
||||
/* Stuff for IEEE float handling */
|
||||
|
||||
#define IEEE_NUMBER_WIDTH 32 /* bits in number */
|
||||
#define IEEE_EXP_WIDTH 8 /* bits in exponent */
|
||||
#define IEEE_MANTISSA_WIDTH 23 /* IEEE_NUMBER_WIDTH - 1 - IEEE_EXP_WIDTH */
|
||||
|
||||
#define IEEE_SIGN_MASK 0x80000000
|
||||
#define IEEE_EXPONENT_MASK 0x7F800000
|
||||
#define IEEE_MANTISSA_MASK 0x007FFFFF
|
||||
#define IEEE_INFINITY IEEE_EXPONENT_MASK
|
||||
|
||||
#define IEEE_IMPLIED_BIT (1 << IEEE_MANTISSA_WIDTH)
|
||||
#define IEEE_INFINITE ((1 << IEEE_EXP_WIDTH) - 1)
|
||||
#define IEEE_BIAS ((1 << (IEEE_EXP_WIDTH - 1)) - 1)
|
||||
|
||||
#define MINUS_INFINITY (signed)0x80000000L
|
||||
#define PLUS_INFINITY 0x7FFFFFFF
|
||||
|
||||
static inline int ieee_float_is_zero (long number)
|
||||
{
|
||||
return(!(number & ~IEEE_SIGN_MASK));
|
||||
}
|
||||
|
||||
/*
|
||||
* simple conversion: ieee floating point to long
|
||||
*/
|
||||
static long tvb_ieee_to_long (tvbuff_t *tvb, int offset)
|
||||
{
|
||||
long number;
|
||||
long sign;
|
||||
long exponent;
|
||||
long mantissa;
|
||||
|
||||
number = tvb_get_ntohl(tvb, offset);
|
||||
sign = number & IEEE_SIGN_MASK;
|
||||
exponent = number & IEEE_EXPONENT_MASK;
|
||||
mantissa = number & IEEE_MANTISSA_MASK;
|
||||
|
||||
if (ieee_float_is_zero(number)) {
|
||||
/* number is zero, unnormalized, or not-a-number */
|
||||
return 0;
|
||||
}
|
||||
if (IEEE_INFINITY == exponent) {
|
||||
/* number is positive or negative infinity, or a special value */
|
||||
return (sign? MINUS_INFINITY: PLUS_INFINITY);
|
||||
}
|
||||
|
||||
exponent = (exponent >> IEEE_MANTISSA_WIDTH) - IEEE_BIAS;
|
||||
if (exponent < 0) {
|
||||
/* number is between zero and one */
|
||||
return 0;
|
||||
}
|
||||
|
||||
mantissa |= IEEE_IMPLIED_BIT;
|
||||
if (exponent <= IEEE_MANTISSA_WIDTH)
|
||||
mantissa >>= IEEE_MANTISSA_WIDTH - exponent;
|
||||
else
|
||||
mantissa <<= exponent - IEEE_MANTISSA_WIDTH;
|
||||
|
||||
if (sign)
|
||||
return -mantissa;
|
||||
else
|
||||
return mantissa;
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue