在“游戏引擎架构”一书中:“.假设我们使用一个浮点变量来跟踪绝对游戏时间(以秒计)。在我们的时钟变量的大小变得如此之大之前,我们能运行多长时间才能使它的值增加1/30秒?答案大约是12.9天。”为什么12.9天,怎么算呢?
发布于 2017-10-23 11:53:54
#include <iostream>
#include <iomanip>
/*
https://en.wikipedia.org/wiki/Machine_epsilon#How_to_determine_machine_epsilon
*/
typedef union
{
int32_t i32;
float f32;
} fi32_t;
float float_epsilon(float nbr)
{
fi32_t flt;
flt.f32 = nbr;
flt.i32++;
return (flt.f32 - nbr);
}
int main()
{
// How to calculate 32-bit floating-point epsilon?
const float one {1.}, ten_mills {10e6};
std::cout << "epsilon for number " << one << " is:\n"
<< std::fixed << std::setprecision(25)
<< float_epsilon(one)
<< std::defaultfloat << "\n\n";
std::cout << "epsilon for number " << ten_mills << " is:\n"
<< std::fixed << std::setprecision(25)
<< float_epsilon(ten_mills)
<< std::defaultfloat << "\n\n";
// In book Game Engine Architecture : "..., let’s say we use a
// floating-point variable to track absolute game time in seconds.
// How long can we run our game before the magnitude of our clock
// variable gets so large that adding 1/30th of a second to it no
// longer changes its value? The answer is roughly 12.9 days."
// Why 12.9 days, how to calculate it ?
const float one_30th {1.f/30}, day_sec {60*60*24};
float time_sec {}, time_sec_old {};
while ((time_sec += one_30th) > time_sec_old)
{
time_sec_old = time_sec;
}
std::cout << "We can run our game for "
<< std::fixed << std::setprecision(5)
<< (time_sec / day_sec)
<< std::defaultfloat << " days.\n";
return EXIT_SUCCESS;
}这输出
epsilon for number 1 is:
0.0000001192092895507812500
epsilon for number 10000000 is:
1.0000000000000000000000000
We can run our game for 12.13630 days.发布于 2016-05-25 19:20:14
这是由于浮点表示的可表达性区域所致。看看我大学的这次讲座。
当指数变大时,实际表示的值之间的实数线上的跳跃增加;当指数较低时,表示的密度较高。给出一个例子,用一个有限的位置值来成像十进制数。给定1.0001e1和1.0002e1,两个值之间的差值为0.0001。但如果指数增加1.0001-10,1.0002-10,则两者之间的差值为0.000100135。很明显,随着指数的增加,这个值会变大。在您讨论的情况下,有可能跳转变得如此大,增长并不能促进最小显着位的舍入增长。
有趣的是,对于表示的限制,更大的浮点类型的准确性更差!仅仅是因为当指数有更多位数时,尾数中位模式的增加在数字线上会跳得更远;就像双倍浮点数的情况一样。
https://stackoverflow.com/questions/37441325
复制相似问题