Skip to content

Commit 256c3a8

Browse files
andreagilardonisebromero
authored andcommitted
Improved and generalized ieee754 is different function
1 parent 706ffdc commit 256c3a8

File tree

3 files changed

+33
-8
lines changed

3 files changed

+33
-8
lines changed

Diff for: src/property/math_utils.h

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
This file is part of the ArduinoIoTCloud library.
3+
4+
Copyright (c) 2024 Arduino SA
5+
6+
This Source Code Form is subject to the terms of the Mozilla Public
7+
License, v. 2.0. If a copy of the MPL was not distributed with this
8+
file, You can obtain one at http://mozilla.org/MPL/2.0/.
9+
*/
10+
#pragma once
11+
#include <math.h>
12+
13+
namespace arduino { namespace math {
14+
15+
template<typename T>
16+
inline bool ieee754_different(const T a, const T b, const T delta = 0.0) {
17+
/* The following comparison is introduced to take into account the very peculiar
18+
* way of handling NaN values by the standard IEEE754.
19+
* We consider two floating point number different if their binary representation is different.
20+
* or if those two IEEE754 values are numbers or zero(which is handled on its own) exceed
21+
* a certain threshold
22+
*/
23+
return memcmp((uint8_t*)&a, (uint8_t*)&b, sizeof(b)) != 0 && (
24+
(fpclassify(a) != FP_NORMAL && fpclassify(a) != FP_ZERO) ||
25+
(fpclassify(b) != FP_NORMAL && fpclassify(b) != FP_ZERO) ||
26+
fabs(a - b) >= delta
27+
);
28+
}
29+
}}

Diff for: src/property/types/CloudFloat.h

+2-4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#define CLOUDFLOAT_H_
2020

2121
#include <math.h>
22+
#include "../math_utils.h"
2223

2324
/******************************************************************************
2425
INCLUDE
@@ -46,10 +47,7 @@ class CloudFloat : public Property {
4647
return _value;
4748
}
4849
virtual bool isDifferentFromCloud() {
49-
if (std::isnan(_value) || std::isnan(_cloud_value)) {
50-
return std::isnan(_value) != std::isnan(_cloud_value);
51-
}
52-
return _value != _cloud_value && fabs(_value - _cloud_value) >= Property::_min_delta_property;
50+
return arduino::math::ieee754_different(_value, _cloud_value, Property::_min_delta_property);
5351
}
5452
virtual void fromCloudToLocal() {
5553
_value = _cloud_value;

Diff for: src/property/types/CloudWrapperFloat.h

+2-4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#define CLOUDWRAPPERFLOAT_H_
2020

2121
#include <math.h>
22+
#include "../math_utils.h"
2223

2324
/******************************************************************************
2425
INCLUDE
@@ -39,10 +40,7 @@ class CloudWrapperFloat : public CloudWrapperBase {
3940
public:
4041
CloudWrapperFloat(float& v) : _primitive_value(v), _cloud_value(v), _local_value(v) {}
4142
virtual bool isDifferentFromCloud() {
42-
if (std::isnan(_primitive_value) || std::isnan(_cloud_value)) {
43-
return std::isnan(_primitive_value) != std::isnan(_cloud_value);
44-
}
45-
return _primitive_value != _cloud_value && fabs(_primitive_value - _cloud_value) >= Property::_min_delta_property;
43+
return arduino::math::ieee754_different(_primitive_value, _cloud_value, Property::_min_delta_property);
4644
}
4745
virtual void fromCloudToLocal() {
4846
_primitive_value = _cloud_value;

0 commit comments

Comments
 (0)