0

I have the following, in C++:

    double clsTime::dblSSM(INT16U uint16Hrs, INT16U uint16Mins, INT16U uint16Secs, INT16U uint16Hunds) {
        double dblHrsAsSecs  = (double)(uint16Hrs % 24) * 3600.0
              ,dblMinsAsSecs = (double)(uint16Mins % 60) * 60.0
              ,dblSecs       = (double)(uint16Secs % 60)
              ,dblHundreths  = (double)(uint16Hunds % 100) / 100.0
              ,dblSSM = dblHrsAsSecs + dblMinsAsSecs + dblSecs + dblHundreths;     
        return dblSSM;                      
    }

When calling this function with:

    dblResult = dblSSM(16, 56, 17, 13);

I can see in the debugger that the results of the intermediate variables are:

    dblHrsAsSecs  = 57600
    dblMinsAsSecs = 3360
    dblSecs       = 17
    dblHundreths  = 0.13

However when combined into dblSSM the result is:

    60977.1

What I want is: 60977.13 which is the correct answer, why is the .03 being dropped and how can I get it included?

To convert back to a string for checking:

    void clsTime::ssmToString(double dblSSM, char* pszBuffer, char szFormat[]) {
      INT8U uint8Hours, uint8Minutes, uint8Seconds, uint8Hundreths;
      double dblDummy;

      assert(pszBuffer != NULL);
      long lngSSM = (long)dblSSM;  
      uint8Hours = (INT8U)(lngSSM / ((long)mscuint16SecsInHour));
      uint8Minutes = (INT8U)((lngSSM % ((long)mscuint16SecsInHour)) /
                                               (long)mscuint16SecsInMinute);
      uint8Seconds = (INT8U)(lngSSM % (long)mscuint16SecsInMinute);
      int8Hundreths = (INT8U)(modf(dblSSM, &dblDummy) * 100.0);  
      sprintf(pszBuffer, szFormat, uint8Hours, uint8Minutes
                         , uint8Seconds, uint8Hundreths);
    }

szFormat is an optional parameter, the default passed in is:

    "%02.2u:%02.2u:%02.2u.%02.2u"
SPlatten
  • 5,334
  • 11
  • 57
  • 128

1 Answers1

2

I think it's not the result but your printing problem.
I have written this program:

#include <iostream> // cout
#include <iomanip> // fixed, setprecision

using namespace std;

double dblSSM(__uint16_t uint16Hrs, __uint16_t uint16Mins, __uint16_t uint16Secs, __uint16_t uint16Hunds) {
        double dblHrsAsSecs  = (double)(uint16Hrs % 24) * 3600.0
              ,dblMinsAsSecs = (double)(uint16Mins % 60) * 60.0
              ,dblSecs       = (double)(uint16Secs % 60)
              ,dblHundreths  = (double)(uint16Hunds % 100) / 100.0
              ,dblSSM = dblHrsAsSecs + dblMinsAsSecs + dblSecs + dblHundreths;     
        return dblSSM;                      
    }

int main () {

    cout << dblSSM(16, 56, 17, 13) << endl; // prints 60977.1
    cout << fixed << setprecision(8)/*output 8 in the decimal part */ << dblSSM(16, 56, 17, 13) << endl; // prints 60977.13000000

    return 0;
}

I think it works as it should.
If you want to print double you should use setprecision and fixed.

EDIT:

cout << fixed << setprecision(12) << ( modf(dblSSM, &dblDummy) * 100.0);

Prints 12.999999999738 so (__uint16_t)(modf(dblSSM, &dblDummy) * 100.0) gives 12. Hacky way to fix this is to use round function, but I suggest you not use doubles unless you really have.