首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在c++中获得长双模的精确方法

在c++中获得长双模的精确方法
EN

Stack Overflow用户
提问于 2014-12-02 13:09:54
回答 4查看 443关注 0票数 2

我正在开发一个涉及定时的c++程序,在这个程序中,我必须确定一个时间的模数(毫秒(长)),而不是双倍。通常情况下,我们会将长转换为双倍,然后使用fmod,或者使用双to和int/long,然后使用%。然而,这也不能给我提供我所需要的准确性。有什么办法可以轻松处理这件事吗?

所以我要找的是:

代码语言:javascript
复制
long a = 9999999; 
double b= 1.42 ;
double answer = a % b;  <<< how do I do this?
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-12-02 13:37:23

在以下问题的评论中:

我希望收到值1.16,并得到一个编译错误。

您可能会期望1.16,因为您认为您的值为1.42。没有。你有一个离1.42最近的双,虽然它足够接近142/100 (这正是1.4199999999999999289457264239899814128875732421875),从一个大的数字中减去它很多次),最终会产生明显的不同。

简而言之,没有办法做你想做的事(a % b)。doublefmod(a, b)之间有一个操作,它执行您所说的操作,但只有理解它应用于doubleab时才能使用它,这两个值在内部没有用十进制表示。

附加注释:

fmod是精确的:它所代表的数学运算的结果总是可以表示为double,而fmod精确地计算这个数学结果。另一方面,其他浮点操作是不精确的,包括在十进制表示“1.42”的情况下从十进制转换。

fmod(9999999.0, 1.42)被精确地计算为1.16000000050038210019920370541512966156005859375。在这个表达式中,9999999.0准确地表示值999999999。该错误仅来自于1.42与142/100之间的差异。

票数 10
EN

Stack Overflow用户

发布于 2014-12-02 13:53:03

如果您可以选择对b使用不动点号,那么您可以得到确切的值。如果您想要将(不动点计算的)精确结果转换为双值,则精度将受到双值表示结果的能力的限制。

代码语言:javascript
复制
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^2b的精度可达2小数点。通过将ab乘以10的幂,可以减少后者的限制。使用任意精度的整数可以避免前者的限制。任意精度整数的实现甚至可能为固定精度算法提供一个接口,允许您避免编写我的示例中的乘法,只需设置适当的epsilon。

票数 2
EN

Stack Overflow用户

发布于 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,但是给出的公式无论是否可以正确工作。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27250284

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档