Changeset 970


Ignore:
Timestamp:
06/30/20 00:34:59 (4 years ago)
Author:
Maciej Komosinski
Message:

Added functions to properly round floating point values to specified precision

Location:
cpp
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • cpp/common/nonstd_math.cpp

    r896 r970  
    11// This file is a part of Framsticks SDK.  http://www.framsticks.com/
    2 // Copyright (C) 1999-2019  Maciej Komosinski and Szymon Ulatowski.
     2// Copyright (C) 1999-2020  Maciej Komosinski and Szymon Ulatowski.
    33// See LICENSE.txt for details.
    44
    55#include "nonstd_math.h"
     6#ifdef USE_PRINTFLOAT_DRAGON4
     7#include <PrintFloat/PrintFloat.h>
     8#else
     9#include <sstream>
     10#endif
    611
    712RandomGenerator &rndGetInstance()
     
    1116}
    1217
     18int doubleToString(double x, int precision, char *buffer, int bufferlen)
     19{
     20#ifdef USE_PRINTFLOAT_DRAGON4
     21        return PrintFloat64(buffer, bufferlen, x,
     22                ((x < -1e17) || (x > 1e17) || ((x < 1e-4) && (x > -1e-4) && (x != 0.0)))
     23                ? PrintFloatFormat_Scientific : PrintFloatFormat_Positional,
     24                precision); //http://www.ryanjuckett.com/programming/printing-floating-point-numbers/
     25#else
     26        char format[10];
     27        sprintf(format, "%%.%dg", precision < 0 ? 17 : precision); //https://stackoverflow.com/questions/16839658/printf-width-specifier-to-maintain-precision-of-floating-point-value
     28        return sprintf(buffer, format, x);
     29#endif
     30}
     31
     32
     33double round(const double x, const int precision)
     34{
     35#ifdef USE_PRINTFLOAT_DRAGON4
     36        char buffer[30];
     37        doubleToString(x, precision, buffer, 30);
     38        double rounded = strtod(buffer, NULL);
     39#else
     40        std::stringstream ss;
     41        ss << std::fixed;
     42        ss.precision(precision); // set the number of places after decimal
     43        ss << x;
     44        double rounded = stod(ss.str());
     45#endif
     46        //printf("%d  %20g \t %20g\n", precision, x, rounded); //for debugging
     47        return rounded;
     48}
    1349
    1450
  • cpp/common/nonstd_math.h

    r913 r970  
    2727inline void rndSetSeed(unsigned int seed) { rndGetInstance().setSeed(seed); }
    2828inline unsigned int rndRandomizeSeed() { return rndGetInstance().randomize(); }
     29
     30
     31
     32// precision==-1 for full precision, or positive values for the number of digits to print past the decimal point.
     33// Allocated buffer with bufferlen=30 is OK.
     34// Returns the number of chars actually used (not including the ending 0).
     35int doubleToString(double x, int precision, char *buffer, int bufferlen);
     36
     37double round(const double x, const int precision);
     38
     39
     40
     41
    2942
    3043//floating point specific numbers
  • cpp/frams/util/sstring-simple.cpp

    r955 r970  
    33#include "extvalue.h"
    44#include <assert.h>
    5 #ifdef USE_PRINTFLOAT_DRAGON4
    6 #include <PrintFloat/PrintFloat.h>
    7 #endif
     5#include <common/nonstd_math.h>
     6
    87
    98void SString::initEmpty()
     
    227226SString SString::valueOf(double d)
    228227{
    229 #ifdef USE_PRINTFLOAT_DRAGON4
    230228        SString tmp;
    231229        char* here = tmp.directWrite(30);
    232         tmp.endWrite(PrintFloat64(here, 30, d,
    233                 ((d < -1e17) || (d > 1e17) || ((d < 1e-4) && (d > -1e-4) && (d != 0.0)))
    234                 ? PrintFloatFormat_Scientific : PrintFloatFormat_Positional,
    235                 -1));//http://www.ryanjuckett.com/programming/printing-floating-point-numbers/
    236 #else
    237         SString tmp = SString::sprintf("%.17g", d); //https://stackoverflow.com/questions/16839658/printf-width-specifier-to-maintain-precision-of-floating-point-value
    238 #endif
     230        tmp.endWrite(doubleToString(d, -1, here, 30));
    239231        if ((!strchr(tmp.c_str(), '.')) && (!strchr(tmp.c_str(), 'e'))) tmp += ".0";
    240232        return tmp;
  • cpp/frams/util/sstring.cpp

    r955 r970  
    11// This file is a part of Framsticks SDK.  http://www.framsticks.com/
    2 // Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
     2// Copyright (C) 1999-2020  Maciej Komosinski and Szymon Ulatowski.
    33// See LICENSE.txt for details.
    44
     
    2323#include "extvalue.h"
    2424#include <assert.h>
    25 #ifdef USE_PRINTFLOAT_DRAGON4
    26 #include <PrintFloat/PrintFloat.h>
    27 #endif
     25#include <common/nonstd_math.h>
    2826
    2927#ifdef MULTITHREADED
     
    367365SString SString::valueOf(double d)
    368366{
    369 #ifdef USE_PRINTFLOAT_DRAGON4
    370367        SString tmp;
    371368        char* here = tmp.directWrite(30);
    372         tmp.endWrite(PrintFloat64(here, 30, d,
    373                 ((d < -1e17) || (d > 1e17) || ((d < 1e-4) && (d > -1e-4) && (d != 0.0)))
    374                 ? PrintFloatFormat_Scientific : PrintFloatFormat_Positional,
    375                 -1));//http://www.ryanjuckett.com/programming/printing-floating-point-numbers/
    376 #else
    377         SString tmp = SString::sprintf("%.17g", d); //https://stackoverflow.com/questions/16839658/printf-width-specifier-to-maintain-precision-of-floating-point-value
    378 #endif
     369        tmp.endWrite(doubleToString(d, -1, here, 30));
    379370        if ((!strchr(tmp.c_str(), '.')) && (!strchr(tmp.c_str(), 'e'))) tmp += ".0";
    380371        return tmp;
Note: See TracChangeset for help on using the changeset viewer.