为什么用“std::chrono”进行时差测量时,与“double”类型相比,用“float”类型给出的有效数字更多
Why does time difference measurement with `std::chrono` give more significant digits with `float` type, compared to `double` type?
我使用std::chrono
工具测量了几个时间差。我用浮球和双人型都做了测试。结果令人吃惊;双精度类型在第7位之后变为...0000000
或...9999999
,而浮点类型继续显示有效数字。
代码:
std::chrono::steady_clock::time_point Start, End;
std::chrono::duration<float, std::ratio<1, 1>> fDuration;
std::chrono::duration<double, std::ratio<1, 1>> dbDuration;
std::cout.precision(20);
std::cout << std::fixed;
for (DWORD dwSleepTime=0; dwSleepTime<=10000; dwSleepTime+=1000)
{
Start = std::chrono::steady_clock::now();
Sleep(dwSleepTime);
End = std::chrono::steady_clock::now();
fDuration = std::chrono::duration_cast<std::chrono::duration<float>>(End - Start);
dbDuration = std::chrono::duration_cast<std::chrono::duration<double>>(End - Start);
std::cout << "Time passed (float) = " << fDuration.count() << std::endl;
std::cout << "Time passed (double) = " << dbDuration.count() << std::endl << std::endl;
}
其输出:
Time passed (float) = 0.00000000000000000000
Time passed (double) = 0.00000000000000000000
Time passed (float) = 1.00005722045898440000
Time passed (double) = 1.00005720000000010000
Time passed (float) = 2.00011444091796870000
Time passed (double) = 2.00011440000000020000
Time passed (float) = 3.00017166137695310000
Time passed (double) = 3.00017159999999980000
Time passed (float) = 4.00022888183593750000
Time passed (double) = 4.00022880000000040000
Time passed (float) = 5.00028610229492190000
Time passed (double) = 5.00028600000000000000
Time passed (float) = 6.00034332275390620000
Time passed (double) = 6.00034319999999970000
Time passed (float) = 7.00040006637573240000
Time passed (double) = 7.00040040000000020000
Time passed (float) = 8.00045776367187500000
Time passed (double) = 8.00045760000000070000
Time passed (float) = 9.00051498413085940000
Time passed (double) = 9.00051479999999950000
Time passed (float) = 10.00057220458984400000
Time passed (double) = 10.00057200000000000000
这种现象背后的原因是什么?在这种特殊情况下,双重类型真的会给出不那么精确的结果吗?
我的系统:
IDE:Visiual Studio 2012
操作系统:Windows 7 x64
CPU:Intel i5 750
double
类型精确地表示值。所以,当你打印它们时,你会看到一个非常接近原始值的值。例如,当原始值为1.0000572,并将其转换为double
时,结果为1.0000557200000000090511775852064602077007293701171875,因为这是double
可以表示的最接近的值。
float
类型表示的值不太精确。转换1.0000572时,结果为1.000057220458984375,因为这是一个接近值,因为float
可以达到1.0000572。
此外,当您使用Visual Studio软件将这些数字转换为十进制进行打印时,只显示前17位数字,因为Visual Studio会停止显示,并将其余数字打印为零。(应该清楚的是,以这种方式打印它们并不意味着float
和double
对象具有这些值。IEEE-754浮点标准清楚地表明,所表示的确切值是我上面显示的值,即1.0000557220458984375和1.0000557200000000090511775852064602077007293701171875。)。高质量软件根据要求将精确值打印到任意数量的十进制数字。)
您想要了解二进制浮点和精度!float
有6位小数精度,double
有16位小数精度(我想,但我一直记错了确切的值;请检查std::numeric_limits<T>::digits10
)。由于二进制浮点不能准确地表示小数点(只有一些,但很多不是),打印二进制浮点值会导致在离开打印例程执行其想要执行的操作时进行一些舍入。当您要求的数字超过digits10
时,四舍五入通常会被推迟,它会打印实际的二进制小数,直到您要求的位数。
在上面描述的情况下,float
版本刚刚开始打印实际值(最多可以有std::numeric_limits<T>::digits
的有效位)。double
版本似乎仍然合理地舍入,尽管要求20位数字已经将其放入了应该/可以/可能显示近似值的区域。当然,这些都与std::chrono
无关,只是关于二进制浮点。
- 数组下标的类型"float*[float]"无效
- 错误:二进制'operator*' 'float'和'float[0]'类型的操作数无效
- 编译器给出错误:format 指定类型 'float *',但参数的类型'double' [-Wformat]
- OPENCL 警告:不兼容的指针类型将'float __global[16]'传递给类型为 '__global float4 的参数 *
- "错误:数组下标的无效类型'float [10001][float]'是什么意思?
- 将"float*"赋值为"float* [1000]"中的不兼容类型
- 数组类型 'float [size]'不可分配
- 错误:二进制'operator*' 'int [1]'和'float'类型的操作数无效
- 转换特征矩阵类型时,错误:在"float"之前预期主表达式
- 功能使用INT和Float类型作为C 中的参数过载
- tensorflow C API中的float数据类型
- 此背包代码显示浮点[float]无效类型错误.可能是什么原因
- typedef float _float32;的声明说明符中的两种或多种数据类型;
- 错误:C++ 中二进制"operator%"类型"float"和"int"的操作数无效
- 如何在C++中为integer、float和double数据类型同时重载运算符
- Waht [错误] 请求 memebr 'area' 在非类类型 'float' 中'r'是什么意思?
- Qt C++ - 不允许使用 QList<float**> 类型
- static_cast是否影响简单类型float的Boost
- 错误:类型 " float(*)[1] " 的参数与类型 " float** " 的参数不兼容
- (程序设计语言C/C++)中的格式值类型float