2017-10-30 3 views
-2

This 내가했습니다 코드입니다 : 기본적으로이 단계는 동급입니까?

#include <iostream> 
#include <limits> 
#include <math.h> 
#include <stdio.h> 

typedef std::numeric_limits<double> dbl; 

double StepValue(double value) { 
    return floor(0.5 + value/0.1) * 0.1; 
} 

void PrintValue(int maxlen, const char *fmt, ...) 
{ 
    char buffer[20]; 
    va_list arglist; 
    va_start(arglist, fmt); 
    vsnprintf(buffer, maxlen, fmt, arglist); 
    va_end(arglist); 

    std::cout << "p: " << buffer << std::endl; 
} 

int main() 
{ 
    std::cout.precision(dbl::max_digits10); 
    std::cout << std::fixed; 

    double inputValue = 13.55121341223423457; 
    std::cout << "v: " << inputValue << std::endl; 

    double steppedValue = StepValue(inputValue); 
    std::cout << "f: " << steppedValue << std::endl; 

    PrintValue(20, "%.1f", inputValue); 
} 

, 나는 inputValue을 가지고 내가 할 수있는 가장 가까운 두 배를 사용하여, I (1 자리 쉼표 이후 인)가 필요합니다 가까운 계단 값으로 반올림 그것 (내가 steppedValue에 지정하는 것)을 대표해라. (상기 점은 개념적으로 0.6을 반환하지만, 그 점이 아니다 의한 부동 소수점 연산에 실제로 13.60000000000000142을 임) inputValue = 13.55121341223423457을 취하고 0.1하는 공정을 사용하여 예를 들어 그럼

는 값 13.6이다.

나중에 inputValue을 사용하고 0.1 단계를 다시 고려하여 vsnprintf 기능을 사용하여 인쇄합니다. 정확히 13.6을 인쇄합니다.

제 질문은 : 내 계단 기능을 사용하거나 vsnprintf을 사용하는 사이에 다른 계단 값으로 반올림되는 ANY inputValue이 존재할 수 있습니까? 즉, 두 단계의 결과에서 내 단계 기능 및 vsnprintf 계산/서로 다른 단계에서 값을 인쇄와 같이 일치하지 않을 수 있습니까?

+1

게시물의 * 텍스트 *를 편집하십시오. 방화벽은 코드 페이지에 대한 링크를 차단하므로 더 적은 인력이 도움을받을 수 있습니다. 화면 스냅 샷을 보내지 마십시오. –

+0

@ThomasMatthews : 완료;) 감사합니다 – markzzz

답변

1

아니요. 10을 곱하는 것이 아니라 정확히 0.1을 나누기 때문에 반올림이 다른 방향으로 갈 수있는 중간 지점에 매우 가까운 숫자가 있습니다. 이것은 컴파일러와 실행 환경에 달려 있습니다.

double inputValue = std::nextafter(0.05, 0.0); 

를 사용하여 비주얼 스튜디오 32 비트 프로그램으로 컴파일 2015 년, 함께 문제를 해결할 수 있습니다 귀하의 라운딩에서 10으로 곱

f: 0.10000000000000001 
p: 0.0 

의 값을 제공하지만, 그 vsnprintf 반올림 처리하는 방법에 따라 달라집니다 .

StepValue에서 return std::round(value * 10.0)/10.0;으로 변경하면 제공된 값의 문제가 해결됩니다.

+0

Uhm interessant! 그렇다면 어떻게 두 작업을 "동기화"할 수 있습니까? 나는'vsnprintf'가 그것의 반올림을 처리하는 방법을 모른다. 물론 그것은 내 "floor + 0.5"approch를 수행하지 않을 것입니다. – markzzz

+0

"둥근"도 사용할 수 있지만 어느 쪽을 묶을 수 있습니까? 그것은 아마도 짐작할 것 같습니다 ... – markzzz

+0

'round'를 사용하는 것은 C 라이브러리의'printf' 패밀리 구현을 정확하게 보지 않고서는 사용하기 가장 좋은 추측 일 것입니다. 이 문제는 반올림 가장자리 값에 매우 가까운 값에서만 발생합니다. – 1201ProgramAlarm