我试图准确地解释质点子午线的交叉,并遇到了关于IEEE浮点算法(圆到最近)的以下问题:
设n是整数,d是一个小正数。有吗?
Y=n* 360 -d
保证地板(y/360)< n?在这里,所有操作(* -
如果这个问题中的360被其他正浮点数取代了呢?(当一个浮点量被分配到间隔均匀的垃圾箱时,也会出现同样的问题。)
发布于 2014-11-05 14:42:45
经过一些实验,我想我可以提供一个部分的答案。让我重新表述这个问题:编写一个函数
int bin(double x, double m)计算
int(floor(x/m))一点儿没错。假设m是正的,并且结果在int的范围内。
第一次尝试是
int bin0(double x, double m) {
return int(std::floor(x / m));
}但是,对于m= 360.0和x= -denorm_min (返回0而不是-1),这是失败的。
因为这个失败只是x接近于零,所以第二次尝试是
int bin1(double x, double m) {
int n = int(std::floor(x / m));
return n == 0 && x < 0 ? -1 : n;
}我相信这会返回准确的答案,前提是n*m完全可以表示为双。对于m= 360.0,这包括所有可表示为32位整数的n。我说的对吗?有证据就好了!
如果这个条件不成立,例如m= 0.1,那么我能想到的最好是
int bin2(double x, double m) {
double z = std::fmod(x, m);
return int(std::floor((x - z)/m + 0.5)) + (z < 0 ? -1 : 0);
}这总是返回正确的结果吗?有没有什么“更清洁”的解决方案?
增编:在我的应用程序中,我只需要得到bin数(偶数或奇数)的奇偶。(我的应用程序是测量测地线多边形的面积,我需要跟踪边缘是以偶数还是奇数的次数围绕着极点。)因此,chux提出的使用remquo的建议是一个不错的建议。不幸的是,(1) std::remquo需要C++11;(2)更严重的是,remquo的glibc实现是错误的;请参阅此错误报告。所以我最终从根本上
int binparity(real x, real m) {
// return the parity of int(floor(x/m))
x = std::fmod(x, 2 * m);
return (x >= 0 && x < m) || x < -m ? 0 : 1
}https://stackoverflow.com/questions/26743389
复制相似问题