C++ 这些步骤是等价的吗?

C++ 这些步骤是等价的吗?,c++,rounding,C++,Rounding,这是我的代码: #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 PrintVal

这是我的代码:

#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);
}
#包括
#包括
#包括
#包括
typedef std::数值_限制dbl;
双步进值(双值){
返回层(0.5+值/0.1)*0.1;
}
无效打印值(int-maxlen,const-char*fmt,…)
{
字符缓冲区[20];
va_列表arglist;
va_启动(参数列表、fmt);
vsnprintf(缓冲区、maxlen、fmt、arglist);
va_end(arglist);

std::cout不,它们不是等价的。因为你要除以0.1(不能精确表示),而不是乘以10(可以),有一个数字非常接近中点,四舍五入将朝不同的方向进行。这可能取决于编译器和执行环境。使用Visual Studio 2015,将编译为32位程序,使用

double inputValue = std::nextafter(0.05, 0.0);
给出的值为

f: 0.10000000000000001
p: 0.0
舍入中乘以10可能会解决问题,但这取决于
vsnprintf
处理舍入的方式


StepValue
更改为
return std::round(值*10.0)/10.0;
将解决我提供的示例值的问题。

请用代码文本编辑您的帖子。防火墙阻止指向代码页的链接,这意味着可以帮助您的人更少。请不要使用屏幕快照。@ThomasMatthews:done;)谢谢Suhm!那么我如何“同步”这两个操作?我不知道
vsnprintf
如何处理它的舍入。当然它不会做我的“地板+0.5”方法。它可以使用“舍入”同样,但哪种情况会打破僵局?这似乎是一个猜测…使用
舍入
可能是最好的猜测,除非你想深入研究你的C库对
printf
家族的实现以准确查看。问题只会发生在非常接近舍入边缘值的值上。是的,但我不能丢弃这些值,即使很小!如果printf家族使用不同类型的舍入会怎样?同样,会有麻烦。一个不同的步骤是很多的…@markzzz
printf
舍入将根据语言规则进行(舍入到最近),而
round
也应该进行相同类型的舍入。