为什么双算术的结果错了?

时间:2017-07-13 13:03:58

标签: c++ double

我在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;                      
    }

使用以下方法调用此函数时

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

我可以在调试器中看到中间变量的结果是:

    dblHrsAsSecs  = 57600
    dblMinsAsSecs = 3360
    dblSecs       = 17
    dblHundreths  = 0.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 个答案:

答案 0 :(得分:2)

我认为这不是结果,而是你的印刷问题 我写了这个程序:

$getNotesSQL = "SELECT pat_id as PAT_ID, note_id as NOTE_ID, CONVERT(char(10), UPDATE_DATE, 120) as UPDATE_DATE ";
$getNotesSQL .= "FROM CLARITY.dbo.HNO_INFO";
$getNotesSQL .= " WHERE ip_note_type_c = ? ";
$getNotesSQL .= " AND  (UPDATE_DATE >= ? AND UPDATE_DATE <= ?)";

if (!$getNotes = sqlsrv_prepare($clarity, $getNotesSQL, array(&$noteType, &$startDate, &$endDate))) {
    echo "getNotesSQL couldn't be prepared\n";
    die(print_r(sqlsrv_errors(), true));
}

$note_type = strval(1);
$start_date = "2017-05-29";
$end_date = "2017-07-11";

/**
$noteType = strval(1);
$startDate = "2017-07-01";
$endDate = "2017-07-11";
*/

function getNotes($getNotes, $note_type, $start_date, $end_date) {

    $noteType = $note_type;
    $startDate = $start_date;
    $endDate = $end_date;

    if (!sqlsrv_execute($getNotes)) {`enter code here`
        echo "getNotes Couldn't be executed\n";
        die(print_r(sqlsrv_errors(), true));
    }

    $noteArray = array();
    $iii=0;
    while ($row = sqlsrv_fetch_array($getNotes, SQLSRV_FETCH_ASSOC)) {
   //     print_r($row);
        $noteArray[$iii] = $row;
        $iii++;
    }

    echo "In getNote Function  iii: (" . $iii .")\n";
    print_r($noteArray);
    return $noteArray;
}



$fetchedNotes = getNotes($getNotes, $note_type, $start_date, $end_date);

print_r($fetchedNotes);

我认为它的工作原理应该如此 如果您想要打印双倍,请使用setprecisionfixed

编辑:

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

打印cout << fixed << setprecision(12) << ( modf(dblSSM, &dblDummy) * 100.0); 以便12.999999999738给出12。 Hacky修复此问题的方法是使用(__uint16_t)(modf(dblSSM, &dblDummy) * 100.0)函数,但我建议你不要使用双精度,除非你真的有。