float_spec.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
3  */
4 
5 #ifndef UAVCAN_MARSHAL_FLOAT_SPEC_HPP_INCLUDED
6 #define UAVCAN_MARSHAL_FLOAT_SPEC_HPP_INCLUDED
7 
8 #include <cmath>
9 #include <uavcan/std.hpp>
10 #include <uavcan/data_type.hpp>
12 #include <uavcan/build_config.hpp>
15 
16 #ifndef UAVCAN_CPP_VERSION
17 # error UAVCAN_CPP_VERSION
18 #endif
19 #if UAVCAN_CPP_VERSION >= UAVCAN_CPP11
20 # include <limits> // Assuming that in C++11 mode all standard headers are available
21 #endif
22 
23 namespace uavcan
24 {
25 
26 template <unsigned BitLen>
28 {
29  struct ErrorNoSuchFloat;
30  typedef typename Select<(sizeof(float) * 8 >= BitLen), float,
31  typename Select<(sizeof(double) * 8 >= BitLen), double,
32  typename Select<(sizeof(long double) * 8 >= BitLen), long double,
33  ErrorNoSuchFloat>::Result>::Result>::Result Type;
34 };
35 
36 
38 {
39  // TODO: Non-IEEE float support
40 
41  static uint16_t nativeIeeeToHalf(float value);
42  static float halfToNativeIeee(uint16_t value);
43 
45 
46  template <unsigned BitLen>
47  static void enforceIeee()
48  {
49  /*
50  * Some compilers may have is_iec559 to be defined false despite the fact that IEEE754 is supported.
51  * An acceptable workaround would be to put an #ifdef here.
52  */
53 #if UAVCAN_CPP_VERSION >= UAVCAN_CPP11
54  StaticAssert<std::numeric_limits<typename NativeFloatSelector<BitLen>::Type>::is_iec559>::check();
55 #endif
56  }
57 
58 public:
59 #if UAVCAN_CPP_VERSION >= UAVCAN_CPP11
60  static std::float_round_style roundstyle() { return std::round_to_nearest; }
62 #endif
63 
64  template <unsigned BitLen>
67  {
68  enforceIeee<BitLen>();
69  union
70  {
73  } u;
74  StaticAssert<sizeof(u.f) * 8 == BitLen>::check();
75  u.f = value;
76  return u.i;
77  }
78 
79  template <unsigned BitLen>
80  static typename NativeFloatSelector<BitLen>::Type
82  {
83  enforceIeee<BitLen>();
84  union
85  {
88  } u;
89  StaticAssert<sizeof(u.f) * 8 == BitLen>::check();
90  u.i = value;
91  return u.f;
92  }
93 };
94 template <>
96 IEEE754Converter::toIeee<16>(typename NativeFloatSelector<16>::Type value)
97 {
98  return nativeIeeeToHalf(value);
99 }
100 template <>
101 inline typename NativeFloatSelector<16>::Type
102 IEEE754Converter::toNative<16>(typename IntegerSpec<16, SignednessUnsigned, CastModeTruncate>::StorageType value)
103 {
104  return halfToNativeIeee(value);
105 }
106 
107 
108 template <unsigned BitLen> struct IEEE754Limits;
109 template <> struct IEEE754Limits<16>
110 {
112  static NativeType max() { return static_cast<NativeType>(65504.0); }
113  static NativeType epsilon() { return static_cast<NativeType>(9.77e-04); }
114 };
115 template <> struct IEEE754Limits<32>
116 {
118  static NativeType max() { return static_cast<NativeType>(3.40282346638528859812e+38); }
119  static NativeType epsilon() { return static_cast<NativeType>(1.19209289550781250000e-7); }
120 };
121 template <> struct IEEE754Limits<64>
122 {
124  static NativeType max() { return static_cast<NativeType>(1.79769313486231570815e+308L); }
125  static NativeType epsilon() { return static_cast<NativeType>(2.22044604925031308085e-16L); }
126 };
127 
128 
129 template <unsigned BitLen_, CastMode CastMode>
130 class UAVCAN_EXPORT FloatSpec : public IEEE754Limits<BitLen_>
131 {
132  FloatSpec();
133 
134 public:
135  enum { BitLen = BitLen_ };
136  enum { MinBitLen = BitLen };
137  enum { MaxBitLen = BitLen };
138  enum { IsPrimitive = 1 };
139 
141 
142 #if UAVCAN_CPP_VERSION < UAVCAN_CPP11
143  enum { IsExactRepresentation = (sizeof(StorageType) * 8 == BitLen) };
144 #else
145  enum { IsExactRepresentation = (sizeof(StorageType) * 8 == BitLen) && std::numeric_limits<StorageType>::is_iec559 };
146 #endif
147 
150 #if UAVCAN_CPP_VERSION >= UAVCAN_CPP11
151  static std::float_round_style roundstyle() { return IEEE754Converter::roundstyle(); }
152 #endif
153 
155  {
156  // cppcheck-suppress duplicateExpression
157  if (CastMode == CastModeSaturate)
158  {
159  saturate(value);
160  }
161  else
162  {
163  truncate(value);
164  }
165  return codec.encode<BitLen>(IEEE754Converter::toIeee<BitLen>(value));
166  }
167 
168  static int decode(StorageType& out_value, ScalarCodec& codec, TailArrayOptimizationMode)
169  {
171  const int res = codec.decode<BitLen>(ieee);
172  if (res <= 0)
173  {
174  return res;
175  }
176  out_value = IEEE754Converter::toNative<BitLen>(ieee);
177  return res;
178  }
179 
181 
182 private:
183  static inline void saturate(StorageType& value)
184  {
185  if ((IsExactRepresentation == 0) && isFinite(value))
186  {
187  if (value > max())
188  {
189  value = max();
190  }
191  else if (value < -max())
192  {
193  value = -max();
194  }
195  else
196  {
197  ; // Valid range
198  }
199  }
200  }
201 
202  static inline void truncate(StorageType& value)
203  {
204  if ((IsExactRepresentation == 0) && isFinite(value))
205  {
206  if (value > max())
207  {
208  value = NumericTraits<StorageType>::infinity();
209  }
210  else if (value < -max())
211  {
212  value = -NumericTraits<StorageType>::infinity();
213  }
214  else
215  {
216  ; // Valid range
217  }
218  }
219  }
220 };
221 
222 
223 template <unsigned BitLen, CastMode CastMode>
225 {
227 
228 public:
229  template <typename Stream> // cppcheck-suppress passedByValue
230  static void stream(Stream& s, const StorageType value, int)
231  {
232  s << value;
233  }
234 };
235 
236 }
237 
238 #endif // UAVCAN_MARSHAL_FLOAT_SPEC_HPP_INCLUDED
uavcan::YamlStreamer< FloatSpec< BitLen, CastMode > >::stream
static void stream(Stream &s, const StorageType value, int)
Definition: float_spec.hpp:230
data_type.hpp
check
ROSCPP_DECL bool check()
uavcan::TailArrayOptimizationMode
TailArrayOptimizationMode
Definition: type_util.hpp:22
uavcan::IEEE754Limits< 64 >::max
static NativeType max()
Definition: float_spec.hpp:124
templates.hpp
uavcan::FloatSpec::roundstyle
static std::float_round_style roundstyle()
Definition: float_spec.hpp:151
uavcan::FloatSpec
Definition: float_spec.hpp:130
uavcan::ScalarCodec::decode
int decode(T &value)
Definition: scalar_codec.hpp:114
uavcan::YamlStreamer< FloatSpec< BitLen, CastMode > >::StorageType
FloatSpec< BitLen, CastMode >::StorageType StorageType
Definition: float_spec.hpp:226
uavcan::IEEE754Limits< 32 >::epsilon
static NativeType epsilon()
Definition: float_spec.hpp:119
uavcan::NativeFloatSelector::Type
Select<(sizeof(float) *8 >=BitLen), float, typename Select<(sizeof(double) *8 >=BitLen), double, typename Select<(sizeof(long double) *8 >=BitLen), long double, ErrorNoSuchFloat >::Result >::Result >::Result Type
Definition: float_spec.hpp:29
uavcan::IEEE754Limits< 16 >::NativeType
NativeFloatSelector< 16 >::Type NativeType
Definition: float_spec.hpp:111
uavcan::IEEE754Converter::toIeee
static IntegerSpec< BitLen, SignednessUnsigned, CastModeTruncate >::StorageType toIeee(typename NativeFloatSelector< BitLen >::Type value)
Definition: float_spec.hpp:66
uavcan::FloatSpec::StorageType
NativeFloatSelector< BitLen >::Type StorageType
Definition: float_spec.hpp:140
uavcan::CastMode
CastMode
Definition: type_util.hpp:17
uavcan::IEEE754Limits< 16 >::max
static NativeType max()
Definition: float_spec.hpp:112
uavcan::IEEE754Converter::roundstyle
static std::float_round_style roundstyle()
UAVCAN requires rounding to nearest for all float conversions.
Definition: float_spec.hpp:61
uavcan::IEEE754Converter::halfToNativeIeee
static float halfToNativeIeee(uint16_t value)
Definition: uc_float_spec.cpp:66
uavcan::IntegerSpec::StorageType
Select<(BitLen<=8), typename Select< IsSigned, int8_t, uint8_t >::Result, typename Select<(BitLen<=16), typename Select< IsSigned, int16_t, uint16_t >::Result, typename Select<(BitLen<=32), typename Select< IsSigned, int32_t, uint32_t >::Result, typename Select<(BitLen<=64), typename Select< IsSigned, int64_t, uint64_t >::Result, ErrorNoSuchInteger >::Result >::Result >::Result >::Result StorageType
Definition: integer_spec.hpp:39
uavcan::StaticAssert
struct UAVCAN_EXPORT StaticAssert
Definition: templates.hpp:29
uavcan::IEEE754Limits< 32 >::max
static NativeType max()
Definition: float_spec.hpp:118
std.hpp
f
f
uavcan::IEEE754Converter::toNative
static NativeFloatSelector< BitLen >::Type toNative(typename IntegerSpec< BitLen, SignednessUnsigned, CastModeTruncate >::StorageType value)
Definition: float_spec.hpp:81
uavcan::uint16_t
std::uint16_t uint16_t
Definition: std.hpp:25
type_util.hpp
uavcan::FloatSpec::encode
static int encode(StorageType value, ScalarCodec &codec, TailArrayOptimizationMode)
Definition: float_spec.hpp:154
uavcan::FloatSpec::truncate
static void truncate(StorageType &value)
Definition: float_spec.hpp:202
uavcan::max
const UAVCAN_EXPORT T & max(const T &a, const T &b)
Definition: templates.hpp:291
uavcan::IEEE754Converter::nativeIeeeToHalf
static uint16_t nativeIeeeToHalf(float value)
Definition: uc_float_spec.cpp:23
uavcan::IEEE754Limits< 32 >::NativeType
NativeFloatSelector< 32 >::Type NativeType
Definition: float_spec.hpp:117
uavcan::IEEE754Converter::enforceIeee
static void enforceIeee()
Definition: float_spec.hpp:47
uavcan::Select
struct UAVCAN_EXPORT Select
Definition: templates.hpp:80
uavcan::FloatSpec::decode
static int decode(StorageType &out_value, ScalarCodec &codec, TailArrayOptimizationMode)
Definition: float_spec.hpp:168
uavcan::IEEE754Limits< 64 >::epsilon
static NativeType epsilon()
Definition: float_spec.hpp:125
UAVCAN_EXPORT
#define UAVCAN_EXPORT
Definition: libuavcan/libuavcan/include/uavcan/build_config.hpp:108
uavcan::IEEE754Limits
Definition: float_spec.hpp:108
uavcan::FloatSpec::saturate
static void saturate(StorageType &value)
Definition: float_spec.hpp:183
build_config.hpp
uavcan::IEEE754Converter
Definition: float_spec.hpp:37
uavcan::NativeFloatSelector
Definition: float_spec.hpp:27
integer_spec.hpp
uavcan::YamlStreamer
class UAVCAN_EXPORT YamlStreamer
Definition: type_util.hpp:84
uavcan::FloatSpec::extendDataTypeSignature
static void extendDataTypeSignature(DataTypeSignature &)
Definition: float_spec.hpp:180
uavcan::IEEE754Limits< 64 >::NativeType
NativeFloatSelector< 64 >::Type NativeType
Definition: float_spec.hpp:123
pyuavcan_v0.dsdl.signature.s
s
Definition: signature.py:73
uavcan::isFinite
bool isFinite(T arg)
Definition: templates.hpp:531
uavcan::IEEE754Limits< 16 >::epsilon
static NativeType epsilon()
Definition: float_spec.hpp:113
uavcan::ScalarCodec::encode
int encode(const T value)
Definition: scalar_codec.hpp:99
uavcan::DataTypeSignature
Definition: data_type.hpp:107
uavcan
Definition: libuavcan/libuavcan/include/uavcan/build_config.hpp:204
uavcan::ScalarCodec
Definition: scalar_codec.hpp:20
uavcan::CastModeSaturate
@ CastModeSaturate
Definition: type_util.hpp:17


uavcan_communicator
Author(s):
autogenerated on Fri Dec 13 2024 03:10:02