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>
18 #include <wsutil/array.h>
20 #define DOUBLE_REPR_LENGTH 27
22 #define SFLOAT_VALUE_INFINITY_PLUS 0x07FE
23 #define SFLOAT_VALUE_NAN 0x07FF
24 #define SFLOAT_VALUE_NRES 0x0800
25 #define SFLOAT_VALUE_RFU 0x0801
26 #define SFLOAT_VALUE_INFINITY_MINUS 0x0802
28 #define FLOAT_VALUE_INFINITY_PLUS 0x007FFFFE
29 #define FLOAT_VALUE_NAN 0x007FFFFF
30 #define FLOAT_VALUE_NRES 0x00800000
31 #define FLOAT_VALUE_RFU 0x00800001
32 #define FLOAT_VALUE_INFINITY_MINUS 0x00800002
35 sfloat_ieee_11073_fvalue_new(fvalue_t
*fv
)
37 fv
->value
.sfloat_ieee_11073
= 0x0000;
41 sfloat_ieee_11073_val_from_literal(fvalue_t
*fv
, const char *s
, bool allow_partial_value _U_
, char **err_msg _U_
)
43 const char *i_char
= s
;
45 uint8_t mantissa_sign
= 0;
46 uint32_t mantissa
= 0;
48 bool fraction_mode
= false;
49 const uint16_t mantissa_max
= 0x07FF;
59 if (c
== '-' && s
[1] == '.')
62 if (c
== '-' && (s
[1] == 'I' || s
[1] == 'i')) {
63 if (!g_ascii_strcasecmp(s
, "-INFINITY")) {
64 fv
->value
.sfloat_ieee_11073
= SFLOAT_VALUE_INFINITY_MINUS
;
69 } else if (c
== 'R' || c
== 'r') {
70 if (!g_ascii_strcasecmp(s
, "RFU")) {
71 fv
->value
.sfloat_ieee_11073
= SFLOAT_VALUE_RFU
;
76 } else if (c
== 'N' || c
== 'n') {
77 if (!g_ascii_strcasecmp(s
, "NRes")) {
78 fv
->value
.sfloat_ieee_11073
= SFLOAT_VALUE_NRES
;
82 if (!g_ascii_strcasecmp(s
, "NaN")) {
83 fv
->value
.sfloat_ieee_11073
= SFLOAT_VALUE_NAN
;
88 } else if (c
== '+') {
89 if (!g_ascii_strcasecmp(s
, "+INFINITY")) {
90 fv
->value
.sfloat_ieee_11073
= SFLOAT_VALUE_INFINITY_PLUS
;
105 while (*i_char
== '0') {
113 if (mantissa
* 10 > (uint32_t) mantissa_max
+ mantissa_sign
) {
120 } else if (c
== '1') {
123 } else if (c
== '2') {
126 } else if (c
== '3') {
129 } else if (c
== '4') {
132 } else if (c
== '5') {
135 } else if (c
== '6') {
138 } else if (c
== '7') {
141 } else if (c
== '8') {
144 } else if (c
== '9') {
147 } else if (c
== '.') {
150 fraction_mode
= true;
153 while (*i_char
== '0') {
155 if (mantissa
* 10 <= (uint32_t) mantissa_max
+ mantissa_sign
) {
157 if (exponent
> -8 - 4) /* -8 is min exponent; 4 is mantissa size */
163 } else if (c
!= '\0') {
164 /* NOTE: Maybe 5e-10, 5e3 notation should be also supported */
168 if (mantissa
> (uint32_t) mantissa_max
+ mantissa_sign
)
171 if (c
!= '.' && fraction_mode
)
175 } while ((c
= *i_char
));
178 mantissa
= ~(mantissa
- 1);
182 /* Transform to normal form */
187 while (mantissa
> 0 && mantissa
% 10 == 0 && exponent
< 7) {
195 fv
->value
.sfloat_ieee_11073
= ((exponent
& 0x0F) << 12) | mantissa
;
201 sfloat_ieee_11073_val_from_uinteger64(fvalue_t
*fv
, const char *s
, uint64_t value _U_
, char **err_msg
)
203 return sfloat_ieee_11073_val_from_literal(fv
, s
, FALSE
, err_msg
);
207 sfloat_ieee_11073_val_from_sinteger64(fvalue_t
*fv
, const char *s
, int64_t value _U_
, char **err_msg
)
209 return sfloat_ieee_11073_val_from_literal(fv
, s
, FALSE
, err_msg
);
213 sfloat_ieee_11073_val_from_double(fvalue_t
*fv
, const char *s
, double value _U_
, char **err_msg
)
215 return sfloat_ieee_11073_val_from_literal(fv
, s
, FALSE
, err_msg
);
219 sfloat_ieee_11073_val_to_repr(wmem_allocator_t
*scope
, const fvalue_t
*fv
, ftrepr_t rtype _U_
, int field_display _U_
)
223 uint16_t mantissa_sign
;
225 char mantissa_buf
[5];
227 uint8_t mantissa_digits
;
229 /* Predefined: +INFINITY, -INFINITY, RFU, NRes, NaN */
230 if (fv
->value
.sfloat_ieee_11073
>= 0x07FE && fv
->value
.sfloat_ieee_11073
<= 0x0802) {
233 switch (fv
->value
.sfloat_ieee_11073
) {
234 case SFLOAT_VALUE_INFINITY_PLUS
:
237 case SFLOAT_VALUE_NAN
:
240 case SFLOAT_VALUE_NRES
:
243 case SFLOAT_VALUE_RFU
:
246 case SFLOAT_VALUE_INFINITY_MINUS
:
250 return wmem_strdup(scope
, s
);
253 /* Longest Signed Float Number: -0.00002048 (11 characters without NULL) */
254 /* Longest Signed Float Number -0.00000001 */
255 /* Longest Signed Nonfloat Number: -20480000000 (12 characters without NULL) */
258 exponent
= fv
->value
.sfloat_ieee_11073
>> 12;
260 exponent
|= 0xF0; /* It is signed (4bits), so make it signed in int8_t */
261 mantissa
= fv
->value
.sfloat_ieee_11073
& 0x07FF;
262 mantissa_sign
= (fv
->value
.sfloat_ieee_11073
& 0x0800);
264 mantissa
= -((int16_t)mantissa
| 0xF800);
267 return wmem_strdup(scope
, "0");
275 mantissa_digits
= snprintf(mantissa_buf
, sizeof(mantissa_buf
), "%"PRIu16
, mantissa
);
276 mantissa_str
= mantissa_buf
;
279 memcpy(buf
+ offset
, mantissa_str
, mantissa_digits
);
280 offset
+= mantissa_digits
;
281 } else if (exponent
> 0) {
282 memcpy(buf
+ offset
, mantissa_str
, mantissa_digits
);
283 offset
+= mantissa_digits
;
285 memset(buf
+ offset
, '0', exponent
);
287 } else /* if (exponent < 0)*/ {
288 if (-exponent
< mantissa_digits
) {
289 memcpy(buf
+ offset
, mantissa_str
, mantissa_digits
+ exponent
);
290 offset
+= mantissa_digits
+ exponent
;
295 memcpy(buf
+ offset
, mantissa_str
+ mantissa_digits
+ exponent
, -exponent
);
304 if (-exponent
- mantissa_digits
> 0) {
305 memset(buf
+ offset
, '0', -exponent
- mantissa_digits
);
306 offset
+= -exponent
- mantissa_digits
;
309 memcpy(buf
+ offset
, mantissa_str
, mantissa_digits
);
310 offset
+= mantissa_digits
;
315 return wmem_strdup(scope
, buf
);
319 sfloat_ieee_11073_value_set(fvalue_t
*fv
, uint32_t value
)
321 fv
->value
.sfloat_ieee_11073
= (uint16_t) value
;
325 sfloat_ieee_11073_value_get(fvalue_t
*fv
)
327 return (uint32_t) fv
->value
.sfloat_ieee_11073
;
330 static uint16_t sfloat_to_normal_form(uint16_t value
)
334 uint8_t mantissa_sign
;
336 if (value
>= 0x07FE && value
<= 0x0802) /* Save special values */
339 mantissa
= value
& 0x07FF;
340 if (value
& 0x0800) {
341 mantissa
= -((int16_t)mantissa
| 0xF800);
347 exponent
= value
>> 12;
349 if (exponent
& 0x08) {
353 while ((!(mantissa
% 10)) && mantissa
!= 0) {
362 return ((((exponent
& 0x80) ? 0x8 : 0x0 ) | (exponent
& 0x7)) << 12) | (mantissa_sign
<< 11) | mantissa
;
366 sfloat_ieee_11073_cmp_eq(const fvalue_t
*a
, const fvalue_t
*b
)
368 return sfloat_to_normal_form(a
->value
.sfloat_ieee_11073
) == sfloat_to_normal_form(b
->value
.sfloat_ieee_11073
);
372 sfloat_ieee_11073_cmp_lt(const fvalue_t
*a
, const fvalue_t
*b
)
376 int16_t a_norm_mantissa
;
377 int16_t b_norm_mantissa
;
378 int8_t a_norm_exponent
;
379 int8_t b_norm_exponent
;
381 a_norm
= sfloat_to_normal_form(a
->value
.sfloat_ieee_11073
);
382 b_norm
= sfloat_to_normal_form(b
->value
.sfloat_ieee_11073
);
384 if (a_norm
== b_norm
)
388 case SFLOAT_VALUE_NAN
:
389 case SFLOAT_VALUE_NRES
:
390 case SFLOAT_VALUE_RFU
:
391 case SFLOAT_VALUE_INFINITY_PLUS
:
393 case SFLOAT_VALUE_INFINITY_MINUS
:
395 case SFLOAT_VALUE_NAN
:
396 case SFLOAT_VALUE_NRES
:
397 case SFLOAT_VALUE_RFU
:
398 case SFLOAT_VALUE_INFINITY_MINUS
: /* Dead, informative case */
400 case SFLOAT_VALUE_INFINITY_PLUS
:
406 a_norm_mantissa
= a_norm
& 0x0FFF;
407 b_norm_mantissa
= b_norm
& 0x0FFF;
409 a_norm_mantissa
|= 0xFFFFF000;
412 b_norm_mantissa
|= 0xFFFFF000;
414 a_norm_exponent
= a_norm
>> 12;
415 b_norm_exponent
= b_norm
>> 12;
417 if (a_norm_exponent
& 0x08) {
418 a_norm_exponent
|= 0xF0;
421 if (b_norm_exponent
& 0x08) {
422 b_norm_exponent
|= 0xF0;
425 if (a_norm_mantissa
== b_norm_mantissa
&& a_norm_exponent
< b_norm_exponent
)
428 if (a_norm_exponent
== b_norm_exponent
&& a_norm_mantissa
< b_norm_mantissa
)
431 if (a_norm_exponent
< b_norm_exponent
) {
432 uint8_t exponent_difference
;
434 exponent_difference
= b_norm_exponent
- a_norm_exponent
;
436 if (exponent_difference
>= 4)
439 while (exponent_difference
--) {
440 b_norm_mantissa
*= 10;
443 uint8_t exponent_difference
;
445 exponent_difference
= a_norm_exponent
- b_norm_exponent
;
447 if (exponent_difference
>= 4)
450 while (exponent_difference
--) {
451 a_norm_mantissa
*= 10;
455 if (a_norm_mantissa
< b_norm_mantissa
)
461 static enum ft_result
462 sfloat_ieee_11073_cmp_order(const fvalue_t
*a
, const fvalue_t
*b
, int *cmp
)
464 if (sfloat_ieee_11073_cmp_lt(a
, b
))
467 *cmp
= sfloat_ieee_11073_cmp_eq(a
, b
) ? 0 : 1;
473 sfloat_ieee_11073_is_zero(const fvalue_t
*a
)
475 return a
->value
.sfloat_ieee_11073
== 0;
479 sfloat_ieee_11073_hash(const fvalue_t
*fv
)
481 int64_t value
= fv
->value
.sfloat_ieee_11073
;
482 return g_int64_hash(&value
);
485 /*============================================================================*/
488 float_ieee_11073_fvalue_new(fvalue_t
*fv
)
490 fv
->value
.float_ieee_11073
= 0x0000;
494 float_ieee_11073_val_from_literal(fvalue_t
*fv
, const char *s
, bool allow_partial_value _U_
, char **err_msg _U_
)
496 const char *i_char
= s
;
498 uint8_t mantissa_sign
= 0;
499 uint32_t mantissa
= 0;
500 int16_t exponent
= 0;
501 bool fraction_mode
= false;
502 const uint32_t mantissa_max
= 0x007FFFFF;
512 if (c
== '-' && s
[1] == '.')
515 if (c
== '-' && (s
[1] == 'I' || s
[1] == 'i')) {
516 if (!g_ascii_strcasecmp(s
, "-INFINITY")) {
517 fv
->value
.float_ieee_11073
= FLOAT_VALUE_INFINITY_MINUS
;
522 } else if (c
== 'R' || c
== 'r') {
523 if (!g_ascii_strcasecmp(s
, "RFU")) {
524 fv
->value
.float_ieee_11073
= FLOAT_VALUE_RFU
;
529 } else if (c
== 'N' || c
== 'n') {
530 if (!g_ascii_strcasecmp(s
, "NRes")) {
531 fv
->value
.float_ieee_11073
= FLOAT_VALUE_NRES
;
535 if (!g_ascii_strcasecmp(s
, "NaN")) {
536 fv
->value
.float_ieee_11073
= FLOAT_VALUE_NAN
;
541 } else if (c
== '+') {
542 if (!g_ascii_strcasecmp(s
, "+INFINITY")) {
543 fv
->value
.float_ieee_11073
= FLOAT_VALUE_INFINITY_PLUS
;
558 while (*i_char
== '0') {
566 if (mantissa
* 10 > mantissa_sign
+ mantissa_max
) {
573 } else if (c
== '1') {
576 } else if (c
== '2') {
579 } else if (c
== '3') {
582 } else if (c
== '4') {
585 } else if (c
== '5') {
588 } else if (c
== '6') {
591 } else if (c
== '7') {
594 } else if (c
== '8') {
597 } else if (c
== '9') {
600 } else if (c
== '.') {
603 fraction_mode
= true;
606 while (*i_char
== '0') {
608 if (mantissa
* 10 <= mantissa_max
+ mantissa_sign
) {
610 if (exponent
> -128 - 7) /* -8 is min exponent; 4 is mantissa size */
616 } else if (c
!= '\0') {
617 /* NOTE: Maybe 5e-10, 5e3 notation should be also supported */
621 if (mantissa
> mantissa_max
+ mantissa_sign
)
624 if (c
!= '.' && fraction_mode
)
628 } while ((c
= *i_char
));
631 mantissa
= ~(mantissa
- 1);
632 mantissa
&= 0x00FFFFFF;
635 /* Transform to normal form */
640 while (mantissa
> 0 && mantissa
% 10 == 0 && exponent
< 127) {
648 fv
->value
.float_ieee_11073
= ((exponent
& 0xFF) << 24) | mantissa
;
654 float_ieee_11073_val_from_uinteger64(fvalue_t
*fv
, const char *s
, uint64_t value _U_
, char **err_msg
)
656 return float_ieee_11073_val_from_literal(fv
, s
, FALSE
, err_msg
);
660 float_ieee_11073_val_from_sinteger64(fvalue_t
*fv
, const char *s
, int64_t value _U_
, char **err_msg
)
662 return float_ieee_11073_val_from_literal(fv
, s
, FALSE
, err_msg
);
666 float_ieee_11073_val_from_double(fvalue_t
*fv
, const char *s
, double value _U_
, char **err_msg
)
668 return float_ieee_11073_val_from_literal(fv
, s
, FALSE
, err_msg
);
672 float_ieee_11073_val_to_repr(wmem_allocator_t
*scope
, const fvalue_t
*fv
, ftrepr_t rtype _U_
, int field_display _U_
)
676 uint32_t mantissa_sign
;
678 char mantissa_buf
[8];
680 uint8_t mantissa_digits
;
682 /* Predefined: +INFINITY, -INFINITY, RFU, NRes, NaN */
683 if (fv
->value
.float_ieee_11073
>= 0x007FFFFE && fv
->value
.float_ieee_11073
<= 0x00800002) {
685 switch (fv
->value
.float_ieee_11073
) {
686 case FLOAT_VALUE_INFINITY_PLUS
:
689 case FLOAT_VALUE_NAN
:
692 case FLOAT_VALUE_NRES
:
695 case FLOAT_VALUE_RFU
:
698 case FLOAT_VALUE_INFINITY_MINUS
:
702 return wmem_strdup(scope
, s
);
705 /* Longest Signed Nonfloat Number: -8388608*(10^-128) (1 character for sign, 7 for mantisa digits, 127 zeros, 1 character for NULL) */
708 exponent
= fv
->value
.float_ieee_11073
>> 24;
710 mantissa
= fv
->value
.float_ieee_11073
& 0x007FFFFF;
711 mantissa_sign
= (fv
->value
.float_ieee_11073
& 0x00800000);
713 mantissa
= (uint32_t)(-((int32_t)(mantissa
| 0xFF000000)));
716 return wmem_strdup(scope
, "0");
724 mantissa_digits
= snprintf(mantissa_buf
, sizeof(mantissa_buf
), "%"PRIu32
, mantissa
);
725 mantissa_str
= mantissa_buf
;
728 memcpy(buf
+ offset
, mantissa_str
, mantissa_digits
);
729 offset
+= mantissa_digits
;
730 } else if (exponent
> 0) {
731 memcpy(buf
+ offset
, mantissa_str
, mantissa_digits
);
732 offset
+= mantissa_digits
;
734 memset(buf
+ offset
, '0', exponent
);
736 } else /* if (exponent < 0)*/ {
737 if (-exponent
< mantissa_digits
) {
738 memcpy(buf
+ offset
, mantissa_str
, mantissa_digits
+ exponent
);
739 offset
+= mantissa_digits
+ exponent
;
744 memcpy(buf
+ offset
, mantissa_str
+ mantissa_digits
+ exponent
, -exponent
);
753 if (-exponent
- mantissa_digits
> 0) {
754 memset(buf
+ offset
, '0', -exponent
- mantissa_digits
);
755 offset
+= -exponent
- mantissa_digits
;
758 memcpy(buf
+ offset
, mantissa_str
, mantissa_digits
);
759 offset
+= mantissa_digits
;
764 return wmem_strdup(scope
, buf
);
768 float_ieee_11073_value_set(fvalue_t
*fv
, uint32_t value
)
770 fv
->value
.float_ieee_11073
= value
;
774 float_ieee_11073_value_get(fvalue_t
*fv
)
776 return fv
->value
.float_ieee_11073
;
779 static uint32_t float_to_normal_form(uint32_t value
)
783 uint8_t mantissa_sign
;
785 if (value
>= 0x007FFFFE && value
<= 0x00800002) /* Save special values */
788 mantissa
= value
& 0x907FFFFF;
789 if (value
& 0x00800000) {
790 mantissa
= (uint32_t)(-((int32_t)(mantissa
| 0xFF000000)));
796 exponent
= value
>> 24;
798 while ((!(mantissa
% 10)) && mantissa
!= 0) {
807 return (exponent
<< 24) | (mantissa_sign
<< 23) | mantissa
;
811 float_ieee_11073_cmp_eq(const fvalue_t
*a
, const fvalue_t
*b
)
813 return float_to_normal_form(a
->value
.float_ieee_11073
) == float_to_normal_form(b
->value
.float_ieee_11073
);
817 float_ieee_11073_cmp_lt(const fvalue_t
*a
, const fvalue_t
*b
)
821 int32_t a_norm_mantissa
;
822 int32_t b_norm_mantissa
;
823 int8_t a_norm_exponent
;
824 int8_t b_norm_exponent
;
826 a_norm
= float_to_normal_form(a
->value
.float_ieee_11073
);
827 b_norm
= float_to_normal_form(b
->value
.float_ieee_11073
);
829 if (a_norm
== b_norm
)
833 case FLOAT_VALUE_NAN
:
834 case FLOAT_VALUE_NRES
:
835 case FLOAT_VALUE_RFU
:
836 case FLOAT_VALUE_INFINITY_PLUS
:
838 case FLOAT_VALUE_INFINITY_MINUS
:
840 case FLOAT_VALUE_NAN
:
841 case FLOAT_VALUE_NRES
:
842 case FLOAT_VALUE_RFU
:
843 case FLOAT_VALUE_INFINITY_MINUS
: /* Dead, informative case */
845 case FLOAT_VALUE_INFINITY_PLUS
:
851 a_norm_mantissa
= a_norm
& 0x00FFFFFF;
852 b_norm_mantissa
= b_norm
& 0x00FFFFFF;
853 if (a_norm
& 0x00800000)
854 a_norm_mantissa
|= 0xFF000000;
856 if (b_norm
& 0x00800000)
857 b_norm_mantissa
|= 0xFF000000;
859 a_norm_exponent
= a_norm
>> 24;
860 b_norm_exponent
= b_norm
>> 24;
862 if (a_norm_mantissa
== b_norm_mantissa
&& a_norm_exponent
< b_norm_exponent
)
865 if (a_norm_exponent
== b_norm_exponent
&& a_norm_mantissa
< b_norm_mantissa
)
868 if (a_norm_exponent
< b_norm_exponent
) {
869 uint8_t exponent_difference
;
871 exponent_difference
= b_norm_exponent
- a_norm_exponent
;
873 if (exponent_difference
>= 7)
876 while (exponent_difference
--) {
877 b_norm_mantissa
*= 10;
880 uint8_t exponent_difference
;
882 exponent_difference
= a_norm_exponent
- b_norm_exponent
;
884 if (exponent_difference
>= 7)
887 while (exponent_difference
--) {
888 a_norm_mantissa
*= 10;
892 if (a_norm_mantissa
< b_norm_mantissa
)
898 static enum ft_result
899 float_ieee_11073_cmp_order(const fvalue_t
*a
, const fvalue_t
*b
, int *cmp
)
901 if (float_ieee_11073_cmp_lt(a
, b
))
904 *cmp
= float_ieee_11073_cmp_eq(a
, b
) ? 0 : 1;
910 float_ieee_11073_is_zero(const fvalue_t
*a
)
912 return a
->value
.float_ieee_11073
== 0;
916 float_ieee_11073_hash(const fvalue_t
*fv
)
918 int64_t value
= fv
->value
.float_ieee_11073
;
919 return g_int64_hash(&value
);
922 /*============================================================================*/
925 ftype_register_ieee_11073_float(void)
928 Size: 16bits = 2 octets
930 Exponent: 4 bits (signed integer - 2's complement)
931 Mantissa: 12 bits (signed integer - 2's complement)
936 Exponent range: from -8 to 7
937 Mantissa range: from -2048 to 2047 (4 digits)
940 + INFINITY [exponent 0, mantissa +(2^11 -2) = 0x07FE]
941 NaN (Not a Number) [exponent 0, mantissa +(2^11 -1) = 0x07FF]
942 NRes (Not at this Resolution) [exponent 0, mantissa -(2^11) = 0x0800]
943 Reserved for future use [exponent 0, mantissa -(2^11 -1) = 0x0801]
944 - INFINITY [exponent 0, mantissa -(2^11 -2) = 0x0802]
947 be carefour when comparing: 1e == 10e-1 == 10e-2 == ... (solution: compare only if the lowest mantissa % 10 != 0)
949 Example: 114 is 0x0072
952 static const ftype_t sfloat_type
= {
953 FT_IEEE_11073_SFLOAT
, /* ftype */
956 sfloat_ieee_11073_fvalue_new
, /* new_value */
957 NULL
, /* copy_value */
958 NULL
, /* free_value */
959 sfloat_ieee_11073_val_from_literal
, /* val_from_literal */
960 NULL
, /* val_from_string */
961 NULL
, /* val_from_charconst */
962 sfloat_ieee_11073_val_from_uinteger64
, /* val_from_uinteger64 */
963 sfloat_ieee_11073_val_from_sinteger64
, /* val_from_sinteger64 */
964 sfloat_ieee_11073_val_from_double
, /* val_from_double */
965 sfloat_ieee_11073_val_to_repr
, /* val_to_string_repr */
967 NULL
, /* val_to_uinteger64 */
968 NULL
, /* val_to_sinteger64 */
969 NULL
, /* val_to_double */
971 { .set_value_uinteger
= sfloat_ieee_11073_value_set
}, /* union set_value */
972 { .get_value_uinteger
= sfloat_ieee_11073_value_get
}, /* union get_value */
974 sfloat_ieee_11073_cmp_order
,
975 NULL
, /* cmp_contains */
976 NULL
, /* cmp_matches */
978 sfloat_ieee_11073_hash
, /* hash */
979 sfloat_ieee_11073_is_zero
, /* is_zero */
980 NULL
, /* is_negative */
983 NULL
, /* bitwise_and */
984 NULL
, /* unary_minus */
993 Size: 32bits = 4 octets
995 Exponent: 1 octet (signed integer - 2's complement)
996 Mantissa: 3 octets (signed integer - 2's complement)
1001 Exponent range: from -128 to 127
1002 Mantissa range: from -8388608 to 8388607 (7 digits)
1005 + INFINITY [exponent 0, mantissa +(2^23 -2) = 0x007FFFFE]
1006 NaN (Not a Number) [exponent 0, mantissa +(2^23 -1) = 0x007FFFFF]
1007 NRes (Not at this Resolution) [exponent 0, mantissa -(2^23) = 0x00800000]
1008 Reserved for future use [exponent 0, mantissa -(2^23-1) = 0x00800001]
1009 - INFINITY [exponent 0, mantissa -(2^23 -2) = 0x00800002]
1012 be carefour when comparing: 1e == 10e-1 == 10e-2 == ... (solution: compare only if the lowest mantissa % 10 != 0)
1014 Example: 36.4 is 0xFF00016C
1018 static const ftype_t float_type
= {
1019 FT_IEEE_11073_FLOAT
, /* ftype */
1022 float_ieee_11073_fvalue_new
, /* new_value */
1023 NULL
, /* copy_value */
1024 NULL
, /* free_value */
1025 float_ieee_11073_val_from_literal
, /* val_from_literal */
1026 NULL
, /* val_from_string */
1027 NULL
, /* val_from_charconst */
1028 float_ieee_11073_val_from_uinteger64
, /* val_from_uinteger64 */
1029 float_ieee_11073_val_from_sinteger64
, /* val_from_sinteger64 */
1030 float_ieee_11073_val_from_double
, /* val_from_double */
1031 float_ieee_11073_val_to_repr
, /* val_to_string_repr */
1033 NULL
, /* val_to_uinteger64 */
1034 NULL
, /* val_to_sinteger64 */
1035 NULL
, /* val_to_double */
1037 { .set_value_uinteger
= float_ieee_11073_value_set
}, /* union set_value */
1038 { .get_value_uinteger
= float_ieee_11073_value_get
}, /* union get_value */
1040 float_ieee_11073_cmp_order
,
1041 NULL
, /* cmp_contains */
1042 NULL
, /* cmp_matches */
1044 float_ieee_11073_hash
, /* hash */
1045 float_ieee_11073_is_zero
, /* is_zero */
1046 NULL
, /* is_negative */
1049 NULL
, /* bitwise_and */
1050 NULL
, /* unary_minus */
1052 NULL
, /* subtract */
1053 NULL
, /* multiply */
1058 ftype_register(FT_IEEE_11073_SFLOAT
, &sfloat_type
);
1059 ftype_register(FT_IEEE_11073_FLOAT
, &float_type
);
1063 ftype_register_pseudofields_ieee_11073_float(int proto
)
1065 static int hf_ft_ieee_11073_sfloat
;
1066 static int hf_ft_ieee_11073_float
;
1068 static hf_register_info hf_ftypes
[] = {
1069 { &hf_ft_ieee_11073_sfloat
,
1070 { "FT_IEEE_11073_SFLOAT", "_ws.ftypes.ieee_11073_sfloat",
1071 FT_IEEE_11073_SFLOAT
, BASE_NONE
, NULL
, 0x00,
1074 { &hf_ft_ieee_11073_float
,
1075 { "FT_IEEE_11073_FLOAT", "_ws.ftypes.ieee_11073_float",
1076 FT_IEEE_11073_FLOAT
, BASE_NONE
, NULL
, 0x00,
1081 proto_register_field_array(proto
, hf_ftypes
, array_length(hf_ftypes
));
1085 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1090 * indent-tabs-mode: nil
1093 * vi: set shiftwidth=4 tabstop=8 expandtab:
1094 * :indentSize=4:tabSize=8:noTabs=true: