diff options
author | Guy Harris <guy@alum.mit.edu> | 2015-02-28 12:35:16 -0800 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2015-02-28 20:35:56 +0000 |
commit | 71308753fec925e618a1b6e9cba25f7a7a407377 (patch) | |
tree | f9f443f7475cd5193b960d0a9c8cc7ba84b57da9 /epan/dissectors/packet-mip6.c | |
parent | 5892d3c42fd29f7c44520978e6cc17c116fb4985 (diff) |
Convert fixed-point binary to floating-point in a portable fashion.
No need to try to construct an IEEE floating-point number by hand, piece
by piece; just sign-extend the value to 32 bits, convert that integral
value to a floating-point value, and divide the result by 32768 to
properly scale the value.
(Yes, in practice, the chances are overwhelming that we'll be running on
a machine with IEEE floating point - people probably won't be running us
on a VAX, and the UN*Xes on which we're likely to run on a System/3x0 or
z/Architecture machine require, and use, the new IEEE floating-point
capabilities - but no need to be gratuitiously non-portable.)
Change-Id: Ie90a61847e68c3b849de2984139a97004a4ad659
Reviewed-on: https://code.wireshark.org/review/7444
Reviewed-by: Guy Harris <guy@alum.mit.edu>
Diffstat (limited to 'epan/dissectors/packet-mip6.c')
-rw-r--r-- | epan/dissectors/packet-mip6.c | 45 |
1 files changed, 21 insertions, 24 deletions
diff --git a/epan/dissectors/packet-mip6.c b/epan/dissectors/packet-mip6.c index 5708fc957c..0c01a59e0b 100644 --- a/epan/dissectors/packet-mip6.c +++ b/epan/dissectors/packet-mip6.c @@ -3108,36 +3108,33 @@ static const value_string mip6_opt_acc_net_id_sub_opt_op_id_type[] = { static float degrees_convert_fixed_to_float(guint value) { - guint mantissa = 0, exponent = 0, sign = 0, position = 0, mask = 1, i; - if (!value) return 0; - /* If negative number save sign bit and take 2' complement*/ - if (value & 0x800000) /* Input value is 24 bit number*/ - { - value -= 1; - value ^= -1; - sign = 1; - } + /* + * RFC 6757 section 3.1.2: + * + * "A 24-bit {latitude,longitude} degree value encoded as a two's + * complement, fixed point number with 9 whole bits." + * + * "9 whole bits" presumably includes the sign bit; 1 sign bit + * plus 8 more bits supports values between -256 and 255, which + * is sufficient to cover -180 to 180. 9 bits plus a sign bit + * would waste a bit. + * + * So we have 1 sign bit plus 8 bits of integral value, followed + * by a binary point, followed by 15 bits of fractional value. + * That means that to get the value, we treat the fixed-point + * number as an integer and divide it by 2^15 = 32768. + */ - /* Find position of left most 1*/ - for (i = 0; i<24; i++) - { - if (value & mask) - position = i; - mask = (mask << 1); + /* Sign-extend to 32 bits */ + if (value & 0x800000) { + value |= 0xFF000000; } - mantissa = (value << (32 - position - 8 - 1)); - mantissa &= 0x007FFFFF; - - if (sign) - mantissa = (mantissa | 0x80000000); - - exponent = (position - 15 + 127) << 23; - - return (float)(mantissa | exponent); /* club mantissa, exponent and sign*/ + /* Cast to a signed value, and divide by 32768; do a floating-point divide */ + return ((float)(gint)value) / 32768.0f; } static void |