2017-07-13 17 views
0

私は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;      
    } 

でこの関数を呼び出す場合:

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

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

私は中間変数の結果は、デバッガで見ることができます

しかし、dblSSMに結合すると、結果は次のようになります。

60977.1 

私が欲しいものは:正しい答えである60977.13、.03がドロップされている理由と、それをどのように取り込むことができますか?チェックのために戻って、文字列に変換するには

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は、オプションのパラメータで、渡されたデフォルトは次のとおりです。私はそれは、結果が、印刷の問題ではありません

"%02.2u:%02.2u:%02.2u.%02.2u" 
+1

どのようにその値を見ますか?たとえば数字をより多く数字で印刷しようとしましたか:https://stackoverflow.com/a/554134/8051589? –

+0

すべての値は、ウォッチウィンドウのデバッガに表示されます。同じ値を使用して文字列に変換すると、その結果が0.03未満であることもわかります。 – SPlatten

+0

デバッガで表示できる桁数が増えるか、表示される桁数だけ表示できますか?もっと数字が表示されるようにしてください。可能ならば、上記の答えのようにstd :: coutを使用してください。 –

答えて

2

と思います。
私はこのプログラムを書いた:

#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; 
} 

は、私はそれが必要として、それがうまくいくと思います。
ダブルを印刷する場合は、setprecisionfixedを使用してください。

EDIT:

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

プリント12.999999999738ので(__uint16_t)(modf(dblSSM, &dblDummy) * 100.0)は、この問題を解決するために12 ハック方法はround機能を使用することです提供しますが、私はあなたが本当に持っていない限り、あなたがダブルスを使用していないお勧めします。

+1

この回答には['bits/stdC++ .h'](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h)と[' using namesapce std; '](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice)は将来の読者には恐ろしい示唆を与えています。 – StoryTeller

+1

引っ込んだDV。それでも、指示を使用すると私はうんざりします。 – StoryTeller

+0

しかし、それは表示の問題ではなく、なぜdblSSMが間違っていますか?どのように修正するのですか? – SPlatten

関連する問題