我正在开发一个涉及定时的c++程序,在这个程序中,我必须确定一个时间的模数(毫秒(长)),而不是双倍。通常情况下,我们会将长转换为双倍,然后使用fmod,或者使用双to和int/long,然后使用%。然而,这也不能给我提供我所需要的准确性。有什么办法可以轻松处理这件事吗?
所以我要找的是:
long a = 9999999;
double b= 1.42 ;
double answer = a % b; <<< how do I do this?发布于 2014-12-02 13:37:23
在以下问题的评论中:
我希望收到值1.16,并得到一个编译错误。
您可能会期望1.16,因为您认为您的值为1.42。没有。你有一个离1.42最近的双,虽然它足够接近142/100 (这正是1.4199999999999999289457264239899814128875732421875),从一个大的数字中减去它很多次),最终会产生明显的不同。
简而言之,没有办法做你想做的事(a % b)。double和fmod(a, b)之间有一个操作,它执行您所说的操作,但只有理解它应用于double值a和b时才能使用它,这两个值在内部没有用十进制表示。
附加注释:
fmod是精确的:它所代表的数学运算的结果总是可以表示为double,而fmod精确地计算这个数学结果。另一方面,其他浮点操作是不精确的,包括在十进制表示“1.42”的情况下从十进制转换。
fmod(9999999.0, 1.42)被精确地计算为1.16000000050038210019920370541512966156005859375。在这个表达式中,9999999.0准确地表示值999999999。该错误仅来自于1.42与142/100之间的差异。
发布于 2014-12-02 13:53:03
如果您可以选择对b使用不动点号,那么您可以得到确切的值。如果您想要将(不动点计算的)精确结果转换为双值,则精度将受到双值表示结果的能力的限制。
long a_fixed = a * 100;
long b_fixed = 142; // b * 100
double answer = a_fixed % b_fixed / 100.0;在上面的示例中,a_fixed % b_fixed是(a % b * 100)的确切值。a必须小于LONG_MAX / 10^2,b的精度可达2小数点。通过将a和b乘以10的幂,可以减少后者的限制。使用任意精度的整数可以避免前者的限制。任意精度整数的实现甚至可能为固定精度算法提供一个接口,允许您避免编写我的示例中的乘法,只需设置适当的epsilon。
发布于 2014-12-02 17:24:55
虽然有一个fmod函数在除以两个double值时会产生一个精确的余数,虽然一个函数可以通过将long值分解成两个与原始值相加的double值来实现long值之间的精确余数,但是只有当除数本身精确地表示为一个双值时,才能使用fmod对每个值进行加和和,这样的技术才会有用。
如果除数可表示为两个整数(例如,X/Y)的商,其乘积将适合于long,则更精确的方法将是计算(((N % X)*Y) % X) / Y。这种方法将产生double值,即使商数(X/Y)不能精确表示,它也最接近于数值完美的结果。注意,第一个N % X可以简化为N,如果N * Y适合于long,但是给出的公式无论是否可以正确工作。
https://stackoverflow.com/questions/27250284
复制相似问题