1 /* FLOATs as specified by ISO/IEEE Std. 11073-20601-2014
3 * Personal Health Devices Transcoding White Paper v1.5
4 * https://www.bluetooth.org/DocMan/handlers/DownloadDoc.ashx?doc_id=272346
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 2001 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
15 #include <ftypes-int.h>
19 #include <wsutil/array.h>
21 #define DOUBLE_REPR_LENGTH 27
23 #define SFLOAT_VALUE_INFINITY_PLUS 0x07FE
24 #define SFLOAT_VALUE_NAN 0x07FF
25 #define SFLOAT_VALUE_NRES 0x0800
26 #define SFLOAT_VALUE_RFU 0x0801
27 #define SFLOAT_VALUE_INFINITY_MINUS 0x0802
29 #define FLOAT_VALUE_INFINITY_PLUS 0x007FFFFE
30 #define FLOAT_VALUE_NAN 0x007FFFFF
31 #define FLOAT_VALUE_NRES 0x00800000
32 #define FLOAT_VALUE_RFU 0x00800001
33 #define FLOAT_VALUE_INFINITY_MINUS 0x00800002
36 sfloat_ieee_11073_fvalue_new(fvalue_t
*fv
)
38 fv
->value
.sfloat_ieee_11073
= 0x0000;
42 sfloat_ieee_11073_val_from_literal(fvalue_t
*fv
, const char *s
, bool allow_partial_value _U_
, char **err_msg _U_
)
44 const char *i_char
= s
;
46 uint8_t mantissa_sign
= 0;
47 uint32_t mantissa
= 0;
49 bool fraction_mode
= false;
50 const uint16_t mantissa_max
= 0x07FF;
60 if (c
== '-' && s
[1] == '.')
63 if (c
== '-' && (s
[1] == 'I' || s
[1] == 'i')) {
64 if (!g_ascii_strcasecmp(s
, "-INFINITY")) {
65 fv
->value
.sfloat_ieee_11073
= SFLOAT_VALUE_INFINITY_MINUS
;
70 } else if (c
== 'R' || c
== 'r') {
71 if (!g_ascii_strcasecmp(s
, "RFU")) {
72 fv
->value
.sfloat_ieee_11073
= SFLOAT_VALUE_RFU
;
77 } else if (c
== 'N' || c
== 'n') {
78 if (!g_ascii_strcasecmp(s
, "NRes")) {
79 fv
->value
.sfloat_ieee_11073
= SFLOAT_VALUE_NRES
;
83 if (!g_ascii_strcasecmp(s
, "NaN")) {
84 fv
->value
.sfloat_ieee_11073
= SFLOAT_VALUE_NAN
;
89 } else if (c
== '+') {
90 if (!g_ascii_strcasecmp(s
, "+INFINITY")) {
91 fv
->value
.sfloat_ieee_11073
= SFLOAT_VALUE_INFINITY_PLUS
;
106 while (*i_char
== '0') {
114 if (mantissa
* 10 > (uint32_t) mantissa_max
+ mantissa_sign
) {
121 } else if (c
== '1') {
124 } else if (c
== '2') {
127 } else if (c
== '3') {
130 } else if (c
== '4') {
133 } else if (c
== '5') {
136 } else if (c
== '6') {
139 } else if (c
== '7') {
142 } else if (c
== '8') {
145 } else if (c
== '9') {
148 } else if (c
== '.') {
151 fraction_mode
= true;
154 while (*i_char
== '0') {
156 if (mantissa
* 10 <= (uint32_t) mantissa_max
+ mantissa_sign
) {
158 if (exponent
> -8 - 4) /* -8 is min exponent; 4 is mantissa size */
164 } else if (c
!= '\0') {
165 /* NOTE: Maybe 5e-10, 5e3 notation should be also supported */
169 if (mantissa
> (uint32_t) mantissa_max
+ mantissa_sign
)
172 if (c
!= '.' && fraction_mode
)
176 } while ((c
= *i_char
));
179 mantissa
= ~(mantissa
- 1);
183 /* Transform to normal form */
188 while (mantissa
> 0 && mantissa
% 10 == 0 && exponent
< 7) {
196 fv
->value
.sfloat_ieee_11073
= ((exponent
& 0x0F) << 12) | mantissa
;
202 sfloat_ieee_11073_val_from_uinteger64(fvalue_t
*fv
, const char *s
, uint64_t value _U_
, char **err_msg
)
204 return sfloat_ieee_11073_val_from_literal(fv
, s
, FALSE
, err_msg
);
208 sfloat_ieee_11073_val_from_sinteger64(fvalue_t
*fv
, const char *s
, int64_t value _U_
, char **err_msg
)
210 return sfloat_ieee_11073_val_from_literal(fv
, s
, FALSE
, err_msg
);
214 sfloat_ieee_11073_val_from_double(fvalue_t
*fv
, const char *s
, double value _U_
, char **err_msg
)
216 return sfloat_ieee_11073_val_from_literal(fv
, s
, FALSE
, err_msg
);
220 sfloat_ieee_11073_val_to_repr(wmem_allocator_t
*scope
, const fvalue_t
*fv
, ftrepr_t rtype _U_
, int field_display _U_
)
224 uint16_t mantissa_sign
;
226 char mantissa_buf
[5];
228 uint8_t mantissa_digits
;
230 /* Predefined: +INFINITY, -INFINITY, RFU, NRes, NaN */
231 if (fv
->value
.sfloat_ieee_11073
>= 0x07FE && fv
->value
.sfloat_ieee_11073
<= 0x0802) {
234 switch (fv
->value
.sfloat_ieee_11073
) {
235 case SFLOAT_VALUE_INFINITY_PLUS
:
238 case SFLOAT_VALUE_NAN
:
241 case SFLOAT_VALUE_NRES
:
244 case SFLOAT_VALUE_RFU
:
247 case SFLOAT_VALUE_INFINITY_MINUS
:
251 return wmem_strdup(scope
, s
);
254 /* Longest Signed Float Number: -0.00002048 (11 characters without NULL) */
255 /* Longest Signed Float Number -0.00000001 */
256 /* Longest Signed Nonfloat Number: -20480000000 (12 characters without NULL) */
259 exponent
= fv
->value
.sfloat_ieee_11073
>> 12;
261 exponent
|= 0xF0; /* It is signed (4bits), so make it signed in int8_t */
262 mantissa
= fv
->value
.sfloat_ieee_11073
& 0x07FF;
263 mantissa_sign
= (fv
->value
.sfloat_ieee_11073
& 0x0800);
265 mantissa
= -((int16_t)mantissa
| 0xF800);
268 return wmem_strdup(scope
, "0");
276 mantissa_digits
= snprintf(mantissa_buf
, sizeof(mantissa_buf
), "%"PRIu16
, mantissa
);
277 mantissa_str
= mantissa_buf
;
280 memcpy(buf
+ offset
, mantissa_str
, mantissa_digits
);
281 offset
+= mantissa_digits
;
282 } else if (exponent
> 0) {
283 memcpy(buf
+ offset
, mantissa_str
, mantissa_digits
);
284 offset
+= mantissa_digits
;
286 memset(buf
+ offset
, '0', exponent
);
288 } else /* if (exponent < 0)*/ {
289 if (-exponent
< mantissa_digits
) {
290 memcpy(buf
+ offset
, mantissa_str
, mantissa_digits
+ exponent
);
291 offset
+= mantissa_digits
+ exponent
;
296 memcpy(buf
+ offset
, mantissa_str
+ mantissa_digits
+ exponent
, -exponent
);
305 if (-exponent
- mantissa_digits
> 0) {
306 memset(buf
+ offset
, '0', -exponent
- mantissa_digits
);
307 offset
+= -exponent
- mantissa_digits
;
310 memcpy(buf
+ offset
, mantissa_str
, mantissa_digits
);
311 offset
+= mantissa_digits
;
316 return wmem_strdup(scope
, buf
);
319 static enum ft_result
320 sfloat_ieee_11073_val_to_double(const fvalue_t
*fv
, double *repr
)
324 uint16_t mantissa_sign
;
326 switch (fv
->value
.sfloat_ieee_11073
) {
327 case SFLOAT_VALUE_INFINITY_PLUS
:
330 case SFLOAT_VALUE_NAN
:
331 case SFLOAT_VALUE_NRES
:
332 case SFLOAT_VALUE_RFU
:
335 case SFLOAT_VALUE_INFINITY_MINUS
:
342 mantissa
= fv
->value
.sfloat_ieee_11073
& 0x07FF;
349 mantissa_sign
= (fv
->value
.sfloat_ieee_11073
& 0x0800);
351 mantissa
= -((int16_t)mantissa
| 0xF800);
353 exponent
= fv
->value
.sfloat_ieee_11073
>> 12;
355 exponent
|= 0xF0; /* It is signed (4bits), so make it signed in int8_t */
357 *repr
= mantissa
* pow(10, exponent
);
363 sfloat_ieee_11073_value_set(fvalue_t
*fv
, uint32_t value
)
365 fv
->value
.sfloat_ieee_11073
= (uint16_t) value
;
369 sfloat_ieee_11073_value_get(fvalue_t
*fv
)
371 return (uint32_t) fv
->value
.sfloat_ieee_11073
;
374 static uint16_t sfloat_to_normal_form(uint16_t value
)
378 uint8_t mantissa_sign
;
380 if (value
>= 0x07FE && value
<= 0x0802) /* Save special values */
383 mantissa
= value
& 0x07FF;
384 if (value
& 0x0800) {
385 mantissa
= -((int16_t)mantissa
| 0xF800);
391 exponent
= value
>> 12;
393 if (exponent
& 0x08) {
397 while ((!(mantissa
% 10)) && mantissa
!= 0) {
406 return ((((exponent
& 0x80) ? 0x8 : 0x0 ) | (exponent
& 0x7)) << 12) | (mantissa_sign
<< 11) | mantissa
;
410 sfloat_ieee_11073_cmp_eq(const fvalue_t
*a
, const fvalue_t
*b
)
412 return sfloat_to_normal_form(a
->value
.sfloat_ieee_11073
) == sfloat_to_normal_form(b
->value
.sfloat_ieee_11073
);
416 sfloat_ieee_11073_cmp_lt(const fvalue_t
*a
, const fvalue_t
*b
)
420 int16_t a_norm_mantissa
;
421 int16_t b_norm_mantissa
;
422 int8_t a_norm_exponent
;
423 int8_t b_norm_exponent
;
425 a_norm
= sfloat_to_normal_form(a
->value
.sfloat_ieee_11073
);
426 b_norm
= sfloat_to_normal_form(b
->value
.sfloat_ieee_11073
);
428 if (a_norm
== b_norm
)
432 case SFLOAT_VALUE_NAN
:
433 case SFLOAT_VALUE_NRES
:
434 case SFLOAT_VALUE_RFU
:
435 case SFLOAT_VALUE_INFINITY_PLUS
:
437 case SFLOAT_VALUE_INFINITY_MINUS
:
439 case SFLOAT_VALUE_NAN
:
440 case SFLOAT_VALUE_NRES
:
441 case SFLOAT_VALUE_RFU
:
442 case SFLOAT_VALUE_INFINITY_MINUS
: /* Dead, informative case */
444 case SFLOAT_VALUE_INFINITY_PLUS
:
450 a_norm_mantissa
= a_norm
& 0x0FFF;
451 b_norm_mantissa
= b_norm
& 0x0FFF;
453 a_norm_mantissa
|= 0xFFFFF000;
456 b_norm_mantissa
|= 0xFFFFF000;
458 a_norm_exponent
= a_norm
>> 12;
459 b_norm_exponent
= b_norm
>> 12;
461 if (a_norm_exponent
& 0x08) {
462 a_norm_exponent
|= 0xF0;
465 if (b_norm_exponent
& 0x08) {
466 b_norm_exponent
|= 0xF0;
469 if (a_norm_mantissa
== b_norm_mantissa
&& a_norm_exponent
< b_norm_exponent
)
472 if (a_norm_exponent
== b_norm_exponent
&& a_norm_mantissa
< b_norm_mantissa
)
475 if (a_norm_exponent
< b_norm_exponent
) {
476 uint8_t exponent_difference
;
478 exponent_difference
= b_norm_exponent
- a_norm_exponent
;
480 if (exponent_difference
>= 4)
483 while (exponent_difference
--) {
484 b_norm_mantissa
*= 10;
487 uint8_t exponent_difference
;
489 exponent_difference
= a_norm_exponent
- b_norm_exponent
;
491 if (exponent_difference
>= 4)
494 while (exponent_difference
--) {
495 a_norm_mantissa
*= 10;
499 if (a_norm_mantissa
< b_norm_mantissa
)
505 static enum ft_result
506 sfloat_ieee_11073_cmp_order(const fvalue_t
*a
, const fvalue_t
*b
, int *cmp
)
508 if (sfloat_ieee_11073_cmp_lt(a
, b
))
511 *cmp
= sfloat_ieee_11073_cmp_eq(a
, b
) ? 0 : 1;
517 sfloat_ieee_11073_is_zero(const fvalue_t
*a
)
519 return a
->value
.sfloat_ieee_11073
== 0;
523 sfloat_ieee_11073_hash(const fvalue_t
*fv
)
525 int64_t value
= fv
->value
.sfloat_ieee_11073
;
526 return g_int64_hash(&value
);
529 /*============================================================================*/
532 float_ieee_11073_fvalue_new(fvalue_t
*fv
)
534 fv
->value
.float_ieee_11073
= 0x0000;
538 float_ieee_11073_val_from_literal(fvalue_t
*fv
, const char *s
, bool allow_partial_value _U_
, char **err_msg _U_
)
540 const char *i_char
= s
;
542 uint8_t mantissa_sign
= 0;
543 uint32_t mantissa
= 0;
544 int16_t exponent
= 0;
545 bool fraction_mode
= false;
546 const uint32_t mantissa_max
= 0x007FFFFF;
556 if (c
== '-' && s
[1] == '.')
559 if (c
== '-' && (s
[1] == 'I' || s
[1] == 'i')) {
560 if (!g_ascii_strcasecmp(s
, "-INFINITY")) {
561 fv
->value
.float_ieee_11073
= FLOAT_VALUE_INFINITY_MINUS
;
566 } else if (c
== 'R' || c
== 'r') {
567 if (!g_ascii_strcasecmp(s
, "RFU")) {
568 fv
->value
.float_ieee_11073
= FLOAT_VALUE_RFU
;
573 } else if (c
== 'N' || c
== 'n') {
574 if (!g_ascii_strcasecmp(s
, "NRes")) {
575 fv
->value
.float_ieee_11073
= FLOAT_VALUE_NRES
;
579 if (!g_ascii_strcasecmp(s
, "NaN")) {
580 fv
->value
.float_ieee_11073
= FLOAT_VALUE_NAN
;
585 } else if (c
== '+') {
586 if (!g_ascii_strcasecmp(s
, "+INFINITY")) {
587 fv
->value
.float_ieee_11073
= FLOAT_VALUE_INFINITY_PLUS
;
602 while (*i_char
== '0') {
610 if (mantissa
* 10 > mantissa_sign
+ mantissa_max
) {
617 } else if (c
== '1') {
620 } else if (c
== '2') {
623 } else if (c
== '3') {
626 } else if (c
== '4') {
629 } else if (c
== '5') {
632 } else if (c
== '6') {
635 } else if (c
== '7') {
638 } else if (c
== '8') {
641 } else if (c
== '9') {
644 } else if (c
== '.') {
647 fraction_mode
= true;
650 while (*i_char
== '0') {
652 if (mantissa
* 10 <= mantissa_max
+ mantissa_sign
) {
654 if (exponent
> -128 - 7) /* -8 is min exponent; 4 is mantissa size */
660 } else if (c
!= '\0') {
661 /* NOTE: Maybe 5e-10, 5e3 notation should be also supported */
665 if (mantissa
> mantissa_max
+ mantissa_sign
)
668 if (c
!= '.' && fraction_mode
)
672 } while ((c
= *i_char
));
675 mantissa
= ~(mantissa
- 1);
676 mantissa
&= 0x00FFFFFF;
679 /* Transform to normal form */
684 while (mantissa
> 0 && mantissa
% 10 == 0 && exponent
< 127) {
692 fv
->value
.float_ieee_11073
= ((exponent
& 0xFF) << 24) | mantissa
;
698 float_ieee_11073_val_from_uinteger64(fvalue_t
*fv
, const char *s
, uint64_t value _U_
, char **err_msg
)
700 return float_ieee_11073_val_from_literal(fv
, s
, FALSE
, err_msg
);
704 float_ieee_11073_val_from_sinteger64(fvalue_t
*fv
, const char *s
, int64_t value _U_
, char **err_msg
)
706 return float_ieee_11073_val_from_literal(fv
, s
, FALSE
, err_msg
);
710 float_ieee_11073_val_from_double(fvalue_t
*fv
, const char *s
, double value _U_
, char **err_msg
)
712 return float_ieee_11073_val_from_literal(fv
, s
, FALSE
, err_msg
);
716 float_ieee_11073_val_to_repr(wmem_allocator_t
*scope
, const fvalue_t
*fv
, ftrepr_t rtype _U_
, int field_display _U_
)
720 uint32_t mantissa_sign
;
722 char mantissa_buf
[8];
724 uint8_t mantissa_digits
;
726 /* Predefined: +INFINITY, -INFINITY, RFU, NRes, NaN */
727 if (fv
->value
.float_ieee_11073
>= 0x007FFFFE && fv
->value
.float_ieee_11073
<= 0x00800002) {
729 switch (fv
->value
.float_ieee_11073
) {
730 case FLOAT_VALUE_INFINITY_PLUS
:
733 case FLOAT_VALUE_NAN
:
736 case FLOAT_VALUE_NRES
:
739 case FLOAT_VALUE_RFU
:
742 case FLOAT_VALUE_INFINITY_MINUS
:
746 return wmem_strdup(scope
, s
);
749 /* Longest Signed Nonfloat Number: -8388608*(10^-128) (1 character for sign, 7 for mantisa digits, 127 zeros, 1 character for NULL) */
752 exponent
= fv
->value
.float_ieee_11073
>> 24;
754 mantissa
= fv
->value
.float_ieee_11073
& 0x007FFFFF;
755 mantissa_sign
= (fv
->value
.float_ieee_11073
& 0x00800000);
757 mantissa
= (uint32_t)(-((int32_t)(mantissa
| 0xFF000000)));
760 return wmem_strdup(scope
, "0");
768 mantissa_digits
= snprintf(mantissa_buf
, sizeof(mantissa_buf
), "%"PRIu32
, mantissa
);
769 mantissa_str
= mantissa_buf
;
772 memcpy(buf
+ offset
, mantissa_str
, mantissa_digits
);
773 offset
+= mantissa_digits
;
774 } else if (exponent
> 0) {
775 memcpy(buf
+ offset
, mantissa_str
, mantissa_digits
);
776 offset
+= mantissa_digits
;
778 memset(buf
+ offset
, '0', exponent
);
780 } else /* if (exponent < 0)*/ {
781 if (-exponent
< mantissa_digits
) {
782 memcpy(buf
+ offset
, mantissa_str
, mantissa_digits
+ exponent
);
783 offset
+= mantissa_digits
+ exponent
;
788 memcpy(buf
+ offset
, mantissa_str
+ mantissa_digits
+ exponent
, -exponent
);
797 if (-exponent
- mantissa_digits
> 0) {
798 memset(buf
+ offset
, '0', -exponent
- mantissa_digits
);
799 offset
+= -exponent
- mantissa_digits
;
802 memcpy(buf
+ offset
, mantissa_str
, mantissa_digits
);
803 offset
+= mantissa_digits
;
808 return wmem_strdup(scope
, buf
);
811 static enum ft_result
812 float_ieee_11073_val_to_double(const fvalue_t
*fv
, double *repr
)
816 uint16_t mantissa_sign
;
818 switch (fv
->value
.float_ieee_11073
) {
819 case FLOAT_VALUE_INFINITY_PLUS
:
822 case FLOAT_VALUE_NAN
:
823 case FLOAT_VALUE_NRES
:
824 case FLOAT_VALUE_RFU
:
827 case FLOAT_VALUE_INFINITY_MINUS
:
834 mantissa
= fv
->value
.float_ieee_11073
& 0x007FFFFF;
840 mantissa_sign
= (fv
->value
.float_ieee_11073
& 0x00800000);
842 mantissa
= (uint32_t)(-((int32_t)(mantissa
| 0xFF000000)));
844 exponent
= fv
->value
.float_ieee_11073
>> 24;
846 *repr
= mantissa
* pow(10, exponent
);
852 float_ieee_11073_value_set(fvalue_t
*fv
, uint32_t value
)
854 fv
->value
.float_ieee_11073
= value
;
858 float_ieee_11073_value_get(fvalue_t
*fv
)
860 return fv
->value
.float_ieee_11073
;
863 static uint32_t float_to_normal_form(uint32_t value
)
867 uint8_t mantissa_sign
;
869 if (value
>= 0x007FFFFE && value
<= 0x00800002) /* Save special values */
872 mantissa
= value
& 0x907FFFFF;
873 if (value
& 0x00800000) {
874 mantissa
= (uint32_t)(-((int32_t)(mantissa
| 0xFF000000)));
880 exponent
= value
>> 24;
882 while ((!(mantissa
% 10)) && mantissa
!= 0) {
891 return (exponent
<< 24) | (mantissa_sign
<< 23) | mantissa
;
895 float_ieee_11073_cmp_eq(const fvalue_t
*a
, const fvalue_t
*b
)
897 return float_to_normal_form(a
->value
.float_ieee_11073
) == float_to_normal_form(b
->value
.float_ieee_11073
);
901 float_ieee_11073_cmp_lt(const fvalue_t
*a
, const fvalue_t
*b
)
905 int32_t a_norm_mantissa
;
906 int32_t b_norm_mantissa
;
907 int8_t a_norm_exponent
;
908 int8_t b_norm_exponent
;
910 a_norm
= float_to_normal_form(a
->value
.float_ieee_11073
);
911 b_norm
= float_to_normal_form(b
->value
.float_ieee_11073
);
913 if (a_norm
== b_norm
)
917 case FLOAT_VALUE_NAN
:
918 case FLOAT_VALUE_NRES
:
919 case FLOAT_VALUE_RFU
:
920 case FLOAT_VALUE_INFINITY_PLUS
:
922 case FLOAT_VALUE_INFINITY_MINUS
:
924 case FLOAT_VALUE_NAN
:
925 case FLOAT_VALUE_NRES
:
926 case FLOAT_VALUE_RFU
:
927 case FLOAT_VALUE_INFINITY_MINUS
: /* Dead, informative case */
929 case FLOAT_VALUE_INFINITY_PLUS
:
935 a_norm_mantissa
= a_norm
& 0x00FFFFFF;
936 b_norm_mantissa
= b_norm
& 0x00FFFFFF;
937 if (a_norm
& 0x00800000)
938 a_norm_mantissa
|= 0xFF000000;
940 if (b_norm
& 0x00800000)
941 b_norm_mantissa
|= 0xFF000000;
943 a_norm_exponent
= a_norm
>> 24;
944 b_norm_exponent
= b_norm
>> 24;
946 if (a_norm_mantissa
== b_norm_mantissa
&& a_norm_exponent
< b_norm_exponent
)
949 if (a_norm_exponent
== b_norm_exponent
&& a_norm_mantissa
< b_norm_mantissa
)
952 if (a_norm_exponent
< b_norm_exponent
) {
953 uint8_t exponent_difference
;
955 exponent_difference
= b_norm_exponent
- a_norm_exponent
;
957 if (exponent_difference
>= 7)
960 while (exponent_difference
--) {
961 b_norm_mantissa
*= 10;
964 uint8_t exponent_difference
;
966 exponent_difference
= a_norm_exponent
- b_norm_exponent
;
968 if (exponent_difference
>= 7)
971 while (exponent_difference
--) {
972 a_norm_mantissa
*= 10;
976 if (a_norm_mantissa
< b_norm_mantissa
)
982 static enum ft_result
983 float_ieee_11073_cmp_order(const fvalue_t
*a
, const fvalue_t
*b
, int *cmp
)
985 if (float_ieee_11073_cmp_lt(a
, b
))
988 *cmp
= float_ieee_11073_cmp_eq(a
, b
) ? 0 : 1;
994 float_ieee_11073_is_zero(const fvalue_t
*a
)
996 return a
->value
.float_ieee_11073
== 0;
1000 float_ieee_11073_hash(const fvalue_t
*fv
)
1002 int64_t value
= fv
->value
.float_ieee_11073
;
1003 return g_int64_hash(&value
);
1006 /*============================================================================*/
1009 ftype_register_ieee_11073_float(void)
1012 Size: 16bits = 2 octets
1014 Exponent: 4 bits (signed integer - 2's complement)
1015 Mantissa: 12 bits (signed integer - 2's complement)
1020 Exponent range: from -8 to 7
1021 Mantissa range: from -2048 to 2047 (4 digits)
1024 + INFINITY [exponent 0, mantissa +(2^11 -2) = 0x07FE]
1025 NaN (Not a Number) [exponent 0, mantissa +(2^11 -1) = 0x07FF]
1026 NRes (Not at this Resolution) [exponent 0, mantissa -(2^11) = 0x0800]
1027 Reserved for future use [exponent 0, mantissa -(2^11 -1) = 0x0801]
1028 - INFINITY [exponent 0, mantissa -(2^11 -2) = 0x0802]
1031 be carefour when comparing: 1e == 10e-1 == 10e-2 == ... (solution: compare only if the lowest mantissa % 10 != 0)
1033 Example: 114 is 0x0072
1036 static const ftype_t sfloat_type
= {
1037 FT_IEEE_11073_SFLOAT
, /* ftype */
1040 sfloat_ieee_11073_fvalue_new
, /* new_value */
1041 NULL
, /* copy_value */
1042 NULL
, /* free_value */
1043 sfloat_ieee_11073_val_from_literal
, /* val_from_literal */
1044 NULL
, /* val_from_string */
1045 NULL
, /* val_from_charconst */
1046 sfloat_ieee_11073_val_from_uinteger64
, /* val_from_uinteger64 */
1047 sfloat_ieee_11073_val_from_sinteger64
, /* val_from_sinteger64 */
1048 sfloat_ieee_11073_val_from_double
, /* val_from_double */
1049 sfloat_ieee_11073_val_to_repr
, /* val_to_string_repr */
1051 NULL
, /* val_to_uinteger64 */
1052 NULL
, /* val_to_sinteger64 */
1053 sfloat_ieee_11073_val_to_double
, /* val_to_double */
1055 { .set_value_uinteger
= sfloat_ieee_11073_value_set
}, /* union set_value */
1056 { .get_value_uinteger
= sfloat_ieee_11073_value_get
}, /* union get_value */
1058 sfloat_ieee_11073_cmp_order
,
1059 NULL
, /* cmp_contains */
1060 NULL
, /* cmp_matches */
1062 sfloat_ieee_11073_hash
, /* hash */
1063 sfloat_ieee_11073_is_zero
, /* is_zero */
1064 NULL
, /* is_negative */
1067 NULL
, /* bitwise_and */
1068 NULL
, /* unary_minus */
1070 NULL
, /* subtract */
1071 NULL
, /* multiply */
1077 Size: 32bits = 4 octets
1079 Exponent: 1 octet (signed integer - 2's complement)
1080 Mantissa: 3 octets (signed integer - 2's complement)
1085 Exponent range: from -128 to 127
1086 Mantissa range: from -8388608 to 8388607 (7 digits)
1089 + INFINITY [exponent 0, mantissa +(2^23 -2) = 0x007FFFFE]
1090 NaN (Not a Number) [exponent 0, mantissa +(2^23 -1) = 0x007FFFFF]
1091 NRes (Not at this Resolution) [exponent 0, mantissa -(2^23) = 0x00800000]
1092 Reserved for future use [exponent 0, mantissa -(2^23-1) = 0x00800001]
1093 - INFINITY [exponent 0, mantissa -(2^23 -2) = 0x00800002]
1096 be carefour when comparing: 1e == 10e-1 == 10e-2 == ... (solution: compare only if the lowest mantissa % 10 != 0)
1098 Example: 36.4 is 0xFF00016C
1102 static const ftype_t float_type
= {
1103 FT_IEEE_11073_FLOAT
, /* ftype */
1106 float_ieee_11073_fvalue_new
, /* new_value */
1107 NULL
, /* copy_value */
1108 NULL
, /* free_value */
1109 float_ieee_11073_val_from_literal
, /* val_from_literal */
1110 NULL
, /* val_from_string */
1111 NULL
, /* val_from_charconst */
1112 float_ieee_11073_val_from_uinteger64
, /* val_from_uinteger64 */
1113 float_ieee_11073_val_from_sinteger64
, /* val_from_sinteger64 */
1114 float_ieee_11073_val_from_double
, /* val_from_double */
1115 float_ieee_11073_val_to_repr
, /* val_to_string_repr */
1117 NULL
, /* val_to_uinteger64 */
1118 NULL
, /* val_to_sinteger64 */
1119 float_ieee_11073_val_to_double
, /* val_to_double */
1121 { .set_value_uinteger
= float_ieee_11073_value_set
}, /* union set_value */
1122 { .get_value_uinteger
= float_ieee_11073_value_get
}, /* union get_value */
1124 float_ieee_11073_cmp_order
,
1125 NULL
, /* cmp_contains */
1126 NULL
, /* cmp_matches */
1128 float_ieee_11073_hash
, /* hash */
1129 float_ieee_11073_is_zero
, /* is_zero */
1130 NULL
, /* is_negative */
1133 NULL
, /* bitwise_and */
1134 NULL
, /* unary_minus */
1136 NULL
, /* subtract */
1137 NULL
, /* multiply */
1142 ftype_register(FT_IEEE_11073_SFLOAT
, &sfloat_type
);
1143 ftype_register(FT_IEEE_11073_FLOAT
, &float_type
);
1147 ftype_register_pseudofields_ieee_11073_float(int proto
)
1149 static int hf_ft_ieee_11073_sfloat
;
1150 static int hf_ft_ieee_11073_float
;
1152 static hf_register_info hf_ftypes
[] = {
1153 { &hf_ft_ieee_11073_sfloat
,
1154 { "FT_IEEE_11073_SFLOAT", "_ws.ftypes.ieee_11073_sfloat",
1155 FT_IEEE_11073_SFLOAT
, BASE_NONE
, NULL
, 0x00,
1158 { &hf_ft_ieee_11073_float
,
1159 { "FT_IEEE_11073_FLOAT", "_ws.ftypes.ieee_11073_float",
1160 FT_IEEE_11073_FLOAT
, BASE_NONE
, NULL
, 0x00,
1165 proto_register_field_array(proto
, hf_ftypes
, array_length(hf_ftypes
));
1169 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1174 * indent-tabs-mode: nil
1177 * vi: set shiftwidth=4 tabstop=8 expandtab:
1178 * :indentSize=4:tabSize=8:noTabs=true: