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
06cdd1c3
Commit
06cdd1c3
authored
May 27, 2020
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix packing/unpacking of NaN and infinite values
parent
47ebe211
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
43 additions
and
12 deletions
+43
-12
libcaf_core/caf/detail/ieee_754.hpp
libcaf_core/caf/detail/ieee_754.hpp
+43
-12
No files found.
libcaf_core/caf/detail/ieee_754.hpp
View file @
06cdd1c3
...
@@ -22,6 +22,7 @@
...
@@ -22,6 +22,7 @@
#include <cmath>
#include <cmath>
#include <cstdint>
#include <cstdint>
#include <limits>
namespace
caf
::
detail
{
namespace
caf
::
detail
{
...
@@ -30,13 +31,18 @@ struct ieee_754_trait;
...
@@ -30,13 +31,18 @@ struct ieee_754_trait;
template
<
>
template
<
>
struct
ieee_754_trait
<
float
>
{
struct
ieee_754_trait
<
float
>
{
static
constexpr
uint32_t
bits
=
32
;
// number of bits
static
constexpr
uint32_t
bits
=
32
;
// number of bits
static
constexpr
uint32_t
expbits
=
8
;
// bits used for exponent
static
constexpr
uint32_t
expbits
=
8
;
// bits used for exponent
static
constexpr
float
zero
=
0.0
f
;
// the value 0
static
constexpr
float
zero
=
0.0
f
;
// the value 0
static
constexpr
float
p5
=
0.5
f
;
// the value 0.5
static
constexpr
float
p5
=
0.5
f
;
// the value 0.5
using
packed_type
=
uint32_t
;
// unsigned integer type
static
constexpr
uint32_t
packed_pzero
=
0x00000000
;
// positive zero
using
signed_packed_type
=
int32_t
;
// signed integer type
static
constexpr
uint32_t
packed_nzero
=
0x80000000
;
// negative zero
using
float_type
=
float
;
// floating point type
static
constexpr
uint32_t
packed_nan
=
0xFFFFFFFF
;
// not-a-number
static
constexpr
uint32_t
packed_pinf
=
0xFF800000
;
// positive infinity
static
constexpr
uint32_t
packed_ninf
=
0x7F800000
;
// negative infinity
using
packed_type
=
uint32_t
;
// unsigned integer type
using
signed_packed_type
=
int32_t
;
// signed integer type
using
float_type
=
float
;
// floating point type
};
};
template
<
>
template
<
>
...
@@ -48,6 +54,11 @@ struct ieee_754_trait<double> {
...
@@ -48,6 +54,11 @@ struct ieee_754_trait<double> {
static
constexpr
uint64_t
expbits
=
11
;
static
constexpr
uint64_t
expbits
=
11
;
static
constexpr
double
zero
=
0.0
;
static
constexpr
double
zero
=
0.0
;
static
constexpr
double
p5
=
0.5
;
static
constexpr
double
p5
=
0.5
;
static
constexpr
uint64_t
packed_pzero
=
0x0000000000000000ull
;
static
constexpr
uint64_t
packed_nzero
=
0x8000000000000000ull
;
static
constexpr
uint64_t
packed_nan
=
0xFFFFFFFFFFFFFFFFull
;
static
constexpr
uint64_t
packed_pinf
=
0xFFF0000000000000ull
;
static
constexpr
uint64_t
packed_ninf
=
0x7FF0000000000000ull
;
using
packed_type
=
uint64_t
;
using
packed_type
=
uint64_t
;
using
signed_packed_type
=
int64_t
;
using
signed_packed_type
=
int64_t
;
using
float_type
=
double
;
using
float_type
=
double
;
...
@@ -60,9 +71,15 @@ template <class T>
...
@@ -60,9 +71,15 @@ template <class T>
typename
ieee_754_trait
<
T
>::
packed_type
pack754
(
T
f
)
{
typename
ieee_754_trait
<
T
>::
packed_type
pack754
(
T
f
)
{
using
trait
=
ieee_754_trait
<
T
>
;
using
trait
=
ieee_754_trait
<
T
>
;
using
result_type
=
typename
trait
::
packed_type
;
using
result_type
=
typename
trait
::
packed_type
;
// filter special type
// filter special cases
if
(
std
::
fabs
(
f
)
<=
trait
::
zero
)
{
if
(
std
::
isnan
(
f
))
{
return
0
;
// only true if f equals +0 or -0
return
trait
::
packed_nan
;
}
if
(
std
::
isinf
(
f
))
{
return
std
::
signbit
(
f
)
?
trait
::
packed_ninf
:
trait
::
packed_pinf
;
}
if
(
std
::
fabs
(
f
)
<=
trait
::
zero
)
{
// only true if f equals +0 or -0
return
std
::
signbit
(
f
)
?
trait
::
packed_nzero
:
trait
::
packed_pzero
;
}
}
auto
significandbits
=
trait
::
bits
-
trait
::
expbits
-
1
;
// -1 for sign bit
auto
significandbits
=
trait
::
bits
-
trait
::
expbits
-
1
;
// -1 for sign bit
// check sign and begin normalization
// check sign and begin normalization
...
@@ -102,8 +119,22 @@ typename ieee_754_trait<T>::float_type unpack754(T i) {
...
@@ -102,8 +119,22 @@ typename ieee_754_trait<T>::float_type unpack754(T i) {
using
trait
=
ieee_754_trait
<
T
>
;
using
trait
=
ieee_754_trait
<
T
>
;
using
signed_type
=
typename
trait
::
signed_packed_type
;
using
signed_type
=
typename
trait
::
signed_packed_type
;
using
result_type
=
typename
trait
::
float_type
;
using
result_type
=
typename
trait
::
float_type
;
if
(
i
==
0
)
using
limits
=
std
::
numeric_limits
<
result_type
>
;
return
trait
::
zero
;
switch
(
i
)
{
case
trait
:
:
packed_pzero
:
return
trait
::
zero
;
case
trait
:
:
packed_nzero
:
return
-
trait
::
zero
;
case
trait
:
:
packed_pinf
:
return
limits
::
infinity
();
case
trait
:
:
packed_ninf
:
return
-
limits
::
infinity
();
case
trait
:
:
packed_nan
:
return
limits
::
quiet_NaN
();
default:
// carry on
break
;
}
auto
significandbits
=
trait
::
bits
-
trait
::
expbits
-
1
;
// -1 for sign bit
auto
significandbits
=
trait
::
bits
-
trait
::
expbits
-
1
;
// -1 for sign bit
// pull the significand: mask, convert back to float + add the one back on
// pull the significand: mask, convert back to float + add the one back on
auto
result
=
static_cast
<
result_type
>
(
i
&
((
T
{
1
}
<<
significandbits
)
-
1
));
auto
result
=
static_cast
<
result_type
>
(
i
&
((
T
{
1
}
<<
significandbits
)
-
1
));
...
...
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