Skip to content

Commit

Permalink
Merge pull request #4641 from telefonicaid/hardening/large-float-numbers
Browse files Browse the repository at this point in the history
FIX improve double2string function to cope with very large float numbers
  • Loading branch information
danielvillalbamota authored Jan 27, 2025
2 parents 78bba77 + 4c908d1 commit 455aa11
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGES_NEXT_RELEASE
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
- Fix: rendering of large float numbers (according IEEE754 standard) (#4642)
- Fix: improve attribute and metadata invalid format dates for DateTime types in logs (#4616)
- Hardening: upgrade microhttpd dependency from 0.9.76 to 1.0.1
- Hardening: upgrade libmosquitto dependency from 2.0.15 to 2.0.20
Expand Down
18 changes: 16 additions & 2 deletions src/lib/common/string.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
*
* Author: Ken Zangelin
*/

#include <stdio.h>
#include <stdlib.h>
#include <string>
Expand Down Expand Up @@ -964,11 +965,17 @@ std::string double2string(double f)
long long intPart = (long long) f;
double diff = f - intPart;
bool isInteger = false;
bool large = false;

// abs value for 'diff'
diff = (diff < 0)? -diff : diff;

if (diff > 0.9999999998)
if (diff > 1)
{
// this is an overflow situation, pe. f = 1.79e308
large = true;
}
else if (diff > 0.9999999998)
{
intPart += 1;
isInteger = true;
Expand All @@ -984,7 +991,14 @@ std::string double2string(double f)
}
else
{
snprintf(buf, bufSize, "%.9f", f);
if (large)
{
snprintf(buf, bufSize, "%.17g", f);
}
else
{
snprintf(buf, bufSize, "%.9f", f);
}

// Clear out any unwanted trailing zeroes
char* last = &buf[strlen(buf) - 1];
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# Copyright 2025 Telefonica Investigacion y Desarrollo, S.A.U
#
# This file is part of Orion Context Broker.
#
# Orion Context Broker is free software: you can redistribute it and/or
# modify it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# Orion Context Broker is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
# General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with Orion Context Broker. If not, see http://www.gnu.org/licenses/.
#
# For those usages not covered by this license please contact with
# iot_support at tid dot es

# VALGRIND_READY - to mark the test ready for valgrindTestSuite.sh

--NAME--
Large float numbers in attributes

--SHELL-INIT--
dbInit CB
brokerStart CB

--SHELL--

# We are using the the limits included in the IEEE754 standard. However, note that
# min non zero cases are rounded to 0 due to how double2string() function is implemented
# (ten digits precision). We could remove that rounding, but consequences may not be
# backward compatible (eg. places where we have now 1.7 could become in 1.666666666666666666669)
#
# 01. Create entity with large float number
# 02. Retrieve entity with large float numbers
#

echo "01. Create entity with large float number"
echo "========================================="
payload='{
"id": "E",
"type": "T",
"A": {
"value": 1.79e308,
"type": "Number"
},
"maxPositive": {
"value": 1.7976931348623157e308,
"type": "Number"
},
"minNonZeroPositive": {
"value": 4.9406564584124654e-324,
"type": "Number"
},
"maxNegative": {
"value": -1.7976931348623157e308,
"type": "Number"
},
"minNonZeroNegative": {
"value": -4.9406564584124654e-324,
"type": "Number"
}
}'
orionCurl --url '/v2/entities' --payload "$payload"
echo
echo


echo "02. Retrieve entity with large float numbers"
echo "============================================"
orionCurl --url '/v2/entities/E'
echo
echo


--REGEXPECT--
01. Create entity with large float number
=========================================
HTTP/1.1 201 Created
Date: REGEX(.*)
Fiware-Correlator: REGEX([0-9a-f\-]{36})
Location: /v2/entities/E?type=T
Content-Length: 0



02. Retrieve entity with large float numbers
============================================
HTTP/1.1 200 OK
Date: REGEX(.*)
Fiware-Correlator: REGEX([0-9a-f\-]{36})
Content-Type: application/json
Content-Length: 358

{
"A": {
"metadata": {},
"type": "Number",
"value": 1.79e+308
},
"id": "E",
"maxNegative": {
"metadata": {},
"type": "Number",
"value": -1.7976931348623157e+308
},
"maxPositive": {
"metadata": {},
"type": "Number",
"value": 1.7976931348623157e+308
},
"minNonZeroNegative": {
"metadata": {},
"type": "Number",
"value": 0
},
"minNonZeroPositive": {
"metadata": {},
"type": "Number",
"value": 0
},
"type": "T"
}


--TEARDOWN--
brokerStop CB
dbDrop CB

0 comments on commit 455aa11

Please sign in to comment.