Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
Actor Framework
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
Actor Framework
Commits
35c6df5c
Commit
35c6df5c
authored
May 28, 2020
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Document and test fixed IEEE 754 packing
parent
06cdd1c3
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
155 additions
and
15 deletions
+155
-15
CHANGELOG.md
CHANGELOG.md
+8
-0
libcaf_core/CMakeLists.txt
libcaf_core/CMakeLists.txt
+1
-0
libcaf_core/test/detail/ieee_754.cpp
libcaf_core/test/detail/ieee_754.cpp
+110
-0
libcaf_core/test/serialization.cpp
libcaf_core/test/serialization.cpp
+36
-15
No files found.
CHANGELOG.md
View file @
35c6df5c
...
@@ -144,6 +144,14 @@ is based on [Keep a Changelog](https://keepachangelog.com).
...
@@ -144,6 +144,14 @@ is based on [Keep a Changelog](https://keepachangelog.com).
-
Constructing a
`typed_actor`
handle from a pointer view failed du to a missing
-
Constructing a
`typed_actor`
handle from a pointer view failed du to a missing
constructor overload. This (explicit) overload now exists and the conversion
constructor overload. This (explicit) overload now exists and the conversion
should work as expected.
should work as expected.
-
Sending floating points to remote actors changed
`infinity`
and
`NaN`
to
garbage values (#1107). The fixed packing / unpacking routines for IEEE 754
values keeps these non-numeric values intact now. It is worth mentioning that
the new algorithm downgrades signaling NaN values to silent NaN values,
because the standard API does not provide predicates to distinct between the
two. This should have no implications for real-world applications, because
actors that produce a signaling NaN trigger trap handlers before being able to
send the result to another actor.
## [0.17.5] - 2020-05-13
## [0.17.5] - 2020-05-13
...
...
libcaf_core/CMakeLists.txt
View file @
35c6df5c
...
@@ -227,6 +227,7 @@ caf_add_test_suites(caf-core-test
...
@@ -227,6 +227,7 @@ caf_add_test_suites(caf-core-test
deep_to_string
deep_to_string
detached_actors
detached_actors
detail.bounds_checker
detail.bounds_checker
detail.ieee_754
detail.ini_consumer
detail.ini_consumer
detail.limited_vector
detail.limited_vector
detail.meta_object
detail.meta_object
...
...
libcaf_core/test/detail/ieee_754.cpp
0 → 100644
View file @
35c6df5c
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2018 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#define CAF_SUITE detail.ieee_754
#include "caf/detail/ieee_754.hpp"
#include "caf/test/dsl.hpp"
#include <limits>
namespace
{
using
caf
::
detail
::
pack754
;
using
caf
::
detail
::
unpack754
;
template
<
class
T
>
T
roundtrip
(
T
x
)
{
return
unpack754
(
pack754
(
x
));
}
using
flimits
=
std
::
numeric_limits
<
float
>
;
using
dlimits
=
std
::
numeric_limits
<
double
>
;
}
// namespace
#define CHECK_RT(value) CAF_CHECK_EQUAL(roundtrip(value), value)
#define CHECK_PRED_RT(pred, value) CAF_CHECK(pred(roundtrip(value)))
#define CHECK_SIGN_RT(value) \
CAF_CHECK_EQUAL(std::signbit(roundtrip(value)), std::signbit(value))
CAF_TEST
(
packing
and
then
unpacking
floats
returns
the
original
value
)
{
CAF_MESSAGE
(
"finite values compare equal"
);
CHECK_RT
(
0.
f
);
CHECK_RT
(
0xCAF
p1
);
CHECK_RT
(
flimits
::
epsilon
());
CHECK_RT
(
flimits
::
min
());
CHECK_RT
(
flimits
::
max
());
CHECK_RT
(
-
0.
f
);
CHECK_RT
(
0xCAF
p1
);
CHECK_RT
(
-
flimits
::
epsilon
());
CHECK_RT
(
-
flimits
::
min
());
CHECK_RT
(
-
flimits
::
max
());
CAF_MESSAGE
(
"packing and unpacking preserves infinity and NaN"
);
CHECK_PRED_RT
(
std
::
isinf
,
flimits
::
infinity
());
CHECK_PRED_RT
(
std
::
isinf
,
-
flimits
::
infinity
());
CHECK_PRED_RT
(
std
::
isnan
,
flimits
::
quiet_NaN
());
CAF_MESSAGE
(
"packing and unpacking preserves the sign bit"
);
CHECK_SIGN_RT
(
0.
f
);
CHECK_SIGN_RT
(
0xCAF
p1
);
CHECK_SIGN_RT
(
flimits
::
epsilon
());
CHECK_SIGN_RT
(
flimits
::
min
());
CHECK_SIGN_RT
(
flimits
::
max
());
CHECK_SIGN_RT
(
flimits
::
infinity
());
CHECK_SIGN_RT
(
-
0.
f
);
CHECK_SIGN_RT
(
-
0xCAF
p1
);
CHECK_SIGN_RT
(
-
flimits
::
epsilon
());
CHECK_SIGN_RT
(
-
flimits
::
min
());
CHECK_SIGN_RT
(
-
flimits
::
max
());
CHECK_SIGN_RT
(
-
flimits
::
infinity
());
}
CAF_TEST
(
packing
and
then
unpacking
doubles
returns
the
original
value
)
{
CAF_MESSAGE
(
"finite values compare equal"
);
CHECK_RT
(
0.
);
CHECK_RT
(
0xCAF
p1
);
CHECK_RT
(
dlimits
::
epsilon
());
CHECK_RT
(
dlimits
::
min
());
CHECK_RT
(
dlimits
::
max
());
CHECK_RT
(
-
0.
);
CHECK_RT
(
0xCAF
p1
);
CHECK_RT
(
-
dlimits
::
epsilon
());
CHECK_RT
(
-
dlimits
::
min
());
CHECK_RT
(
-
dlimits
::
max
());
CAF_MESSAGE
(
"packing and unpacking preserves infinity and NaN"
);
CHECK_PRED_RT
(
std
::
isinf
,
dlimits
::
infinity
());
CHECK_PRED_RT
(
std
::
isinf
,
-
dlimits
::
infinity
());
CHECK_PRED_RT
(
std
::
isnan
,
dlimits
::
quiet_NaN
());
CAF_MESSAGE
(
"packing and unpacking preserves the sign bit"
);
CHECK_SIGN_RT
(
0.
);
CHECK_SIGN_RT
(
0xCAF
p1
);
CHECK_SIGN_RT
(
dlimits
::
epsilon
());
CHECK_SIGN_RT
(
dlimits
::
min
());
CHECK_SIGN_RT
(
dlimits
::
max
());
CHECK_SIGN_RT
(
dlimits
::
infinity
());
CHECK_SIGN_RT
(
-
0.
);
CHECK_SIGN_RT
(
-
0xCAF
p1
);
CHECK_SIGN_RT
(
-
dlimits
::
epsilon
());
CHECK_SIGN_RT
(
-
dlimits
::
min
());
CHECK_SIGN_RT
(
-
dlimits
::
max
());
CHECK_SIGN_RT
(
-
dlimits
::
infinity
());
}
libcaf_core/test/serialization.cpp
View file @
35c6df5c
...
@@ -87,7 +87,13 @@ struct fixture : test_coordinator_fixture<> {
...
@@ -87,7 +87,13 @@ struct fixture : test_coordinator_fixture<> {
int32_t
i32
=
-
345
;
int32_t
i32
=
-
345
;
int64_t
i64
=
-
1234567890123456789ll
;
int64_t
i64
=
-
1234567890123456789ll
;
float
f32
=
3.45
f
;
float
f32
=
3.45
f
;
float
f32_nan
=
std
::
numeric_limits
<
float
>::
quiet_NaN
();
float
f32_pos_inf
=
std
::
numeric_limits
<
float
>::
infinity
();
float
f32_neg_inf
=
-
std
::
numeric_limits
<
float
>::
infinity
();
double
f64
=
54.3
;
double
f64
=
54.3
;
double
f64_nan
=
std
::
numeric_limits
<
double
>::
quiet_NaN
();
double
f64_pos_inf
=
std
::
numeric_limits
<
double
>::
infinity
();
double
f64_neg_inf
=
-
std
::
numeric_limits
<
double
>::
infinity
();
timestamp
ts
=
timestamp
{
timestamp
::
duration
{
1478715821
*
1000000000ll
}};
timestamp
ts
=
timestamp
{
timestamp
::
duration
{
1478715821
*
1000000000ll
}};
test_enum
te
=
test_enum
::
b
;
test_enum
te
=
test_enum
::
b
;
std
::
string
str
=
"Lorem ipsum dolor sit amet."
;
std
::
string
str
=
"Lorem ipsum dolor sit amet."
;
...
@@ -174,24 +180,19 @@ struct is_message {
...
@@ -174,24 +180,19 @@ struct is_message {
#define CHECK_RT(val) CAF_CHECK_EQUAL(val, roundtrip(val))
#define CHECK_RT(val) CAF_CHECK_EQUAL(val, roundtrip(val))
#define CHECK_PRED_RT(pred, value) CAF_CHECK(pred(roundtrip(value)))
#define CHECK_SIGN_RT(value) \
CAF_CHECK_EQUAL(std::signbit(roundtrip(value)), std::signbit(value))
#define CHECK_MSG_RT(val) CAF_CHECK_EQUAL(val, msg_roundtrip(val))
#define CHECK_MSG_RT(val) CAF_CHECK_EQUAL(val, msg_roundtrip(val))
CAF_TEST_FIXTURE_SCOPE
(
serialization_tests
,
fixture
)
#define CHECK_PRED_MSG_RT(pred, value) CAF_CHECK(pred(msg_roundtrip(value))
)
CAF_TEST
(
ieee_754_conversion
)
{
#define CHECK_SIGN_MSG_RT(value) \
// check conversion of float
CAF_CHECK_EQUAL(std::signbit(msg_roundtrip(value)), std::signbit(value))
float
f1
=
3.1415925
f
;
// float value
auto
p1
=
caf
::
detail
::
pack754
(
f1
);
// packet value
CAF_TEST_FIXTURE_SCOPE
(
serialization_tests
,
fixture
)
CAF_CHECK_EQUAL
(
p1
,
static_cast
<
decltype
(
p1
)
>
(
0x40490FDA
));
auto
u1
=
caf
::
detail
::
unpack754
(
p1
);
// unpacked value
CAF_CHECK_EQUAL
(
f1
,
u1
);
// check conversion of double
double
f2
=
3.14159265358979311600
;
// double value
auto
p2
=
caf
::
detail
::
pack754
(
f2
);
// packet value
CAF_CHECK_EQUAL
(
p2
,
static_cast
<
decltype
(
p2
)
>
(
0x400921FB54442D18
));
auto
u2
=
caf
::
detail
::
unpack754
(
p2
);
// unpacked value
CAF_CHECK_EQUAL
(
f2
,
u2
);
}
CAF_TEST
(
serializing
and
then
deserializing
produces
the
same
value
)
{
CAF_TEST
(
serializing
and
then
deserializing
produces
the
same
value
)
{
CHECK_RT
(
i32
);
CHECK_RT
(
i32
);
...
@@ -202,6 +203,16 @@ CAF_TEST(serializing and then deserializing produces the same value) {
...
@@ -202,6 +203,16 @@ CAF_TEST(serializing and then deserializing produces the same value) {
CHECK_RT
(
te
);
CHECK_RT
(
te
);
CHECK_RT
(
str
);
CHECK_RT
(
str
);
CHECK_RT
(
rs
);
CHECK_RT
(
rs
);
CHECK_PRED_RT
(
std
::
isnan
,
f32_nan
);
CHECK_PRED_RT
(
std
::
isinf
,
f32_pos_inf
);
CHECK_PRED_RT
(
std
::
isinf
,
f32_neg_inf
);
CHECK_PRED_RT
(
std
::
isnan
,
f64_nan
);
CHECK_PRED_RT
(
std
::
isinf
,
f64_pos_inf
);
CHECK_PRED_RT
(
std
::
isinf
,
f64_neg_inf
);
CHECK_SIGN_RT
(
f32_pos_inf
);
CHECK_SIGN_RT
(
f32_neg_inf
);
CHECK_SIGN_RT
(
f64_pos_inf
);
CHECK_SIGN_RT
(
f64_neg_inf
);
}
}
CAF_TEST
(
messages
serialize
and
deserialize
their
content
)
{
CAF_TEST
(
messages
serialize
and
deserialize
their
content
)
{
...
@@ -213,6 +224,16 @@ CAF_TEST(messages serialize and deserialize their content) {
...
@@ -213,6 +224,16 @@ CAF_TEST(messages serialize and deserialize their content) {
CHECK_MSG_RT
(
te
);
CHECK_MSG_RT
(
te
);
CHECK_MSG_RT
(
str
);
CHECK_MSG_RT
(
str
);
CHECK_MSG_RT
(
rs
);
CHECK_MSG_RT
(
rs
);
CHECK_PRED_MSG_RT
(
std
::
isnan
,
f32_nan
);
CHECK_PRED_MSG_RT
(
std
::
isinf
,
f32_pos_inf
);
CHECK_PRED_MSG_RT
(
std
::
isinf
,
f32_neg_inf
);
CHECK_PRED_MSG_RT
(
std
::
isnan
,
f64_nan
);
CHECK_PRED_MSG_RT
(
std
::
isinf
,
f64_pos_inf
);
CHECK_PRED_MSG_RT
(
std
::
isinf
,
f64_neg_inf
);
CHECK_SIGN_MSG_RT
(
f32_pos_inf
);
CHECK_SIGN_MSG_RT
(
f32_neg_inf
);
CHECK_SIGN_MSG_RT
(
f64_pos_inf
);
CHECK_SIGN_MSG_RT
(
f64_neg_inf
);
}
}
CAF_TEST
(
raw_arrays
)
{
CAF_TEST
(
raw_arrays
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment