C++ 为什么模数除法 (%) 仅适用于整数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6102948/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 19:30:06  来源:igfitidea点击:

Why does modulus division (%) only work with integers?

c++c

提问by Brendan Long

I recently ran into an issuethat could easily be solved using modulus division, but the input was a float:

我最近遇到了一个可以使用模数除法轻松解决的问题,但输入是一个浮点数:

Given a periodic function (e.g. sin) and a computer function that can only compute it within the period range (e.g. [-π, π]), make a function that can handle any input.

给定一个周期函数(例如sin)和一个只能在周期范围内计算它的计算机函数(例如 [-π, π]),制作一个可以处理任何输入的函数。

The "obvious" solution is something like:

“明显”的解决方案是这样的:

#include <cmath>

float sin(float x){
    return limited_sin((x + M_PI) % (2 *M_PI) - M_PI);
}

Why doesn't this work? I get this error:

为什么这不起作用?我收到此错误:

error: invalid operands of types double and double to binary operator %

Interestingly, it does work in Python:

有趣的是,它确实适用于 Python:

def sin(x):
    return limited_sin((x + math.pi) % (2 * math.pi) - math.pi)

采纳答案by AnT

Because the normal mathematical notion of "remainder" is only applicable to integer division. i.e. division that is required to generate integer quotient.

因为“余数”的正常数学概念仅适用于整数除法。即生成整数商所需的除法。

In order to extend the concept of "remainder" to real numbers you have to introduce a new kind of "hybrid" operation that would generate integerquotient for realoperands. Core C language does not support such operation, but it is provided as a standard library fmodfunction, as well as remainderfunction in C99. (Note that these functions are not the same and have some peculiarities. In particular, they do not follow the rounding rules of integer division.)

为了将“余数”的概念扩展到实数,您必须引入一种新的“混合”运算,该运算将为数操作数生成整数商。核心 C 语言不支持这种操作,但它作为标准库函数提供,以及在 C99 中的函数。(注意,这些函数并不相同,有一些特殊性。特别是,它们不遵循整数除法的舍入规则。)fmodremainder

回答by Doug Stephen

You're looking for fmod().

您正在寻找fmod()

I guess to more specifically answer your question, in older languages the %operator was just defined as integer modular division and in newer languages they decided to expand the definition of the operator.

我想更具体地回答您的问题,在较旧的语言中,%运算符只是被定义为整数模除法,而在较新的语言中,他们决定扩展运算符的定义。

EDIT:If I were to wager a guess why, I would say it's because the idea of modular arithmetic originates in number theory and deals specifically with integers.

编辑:如果我要猜猜为什么,我会说这是因为模算术的想法起源于数论并专门处理整数。

回答by Jerry Coffin

I can't really say for sure, but I'd guess it's mostly historical. Quite a few early C compilers didn't support floating point at all. It was added on later, and even then not as completely -- mostly the data type was added, and the mostprimitive operations supported in the language, but everything else left to the standard library.

我不能肯定地说,但我想这主要是历史性的。相当多的早期 C 编译器根本不支持浮点。它是后来添加的,即使那样也不完全——主要是添加了数据类型,以及语言中支持的原始的操作,但其他一切都留给了标准库。

回答by Mark Elliot

The modulo operator %in C and C++ is defined for two integers, however, there is an fmod()function available for usage with doubles.

%C 和 C++ 中的模运算符是为两个整数定义的,但是,有一个fmod()函数可用于双精度数。

回答by Yu Hao

The constraints are in the standards:

限制在标准中:

C11(ISO/IEC 9899:201x) §6.5.5 Multiplicative operators

C11(ISO/IEC 9899:201x) §6.5.5乘法运算符

Each of the operands shall have arithmetic type. The operands of the % operator shall have integer type.

每个操作数都应具有算术类型。% 运算符的操作数应为整数类型。

C++11(ISO/IEC 14882:2011) §5.6 Multiplicative operators

C++11(ISO/IEC 14882:2011) §5.6乘法运算符

The operands of * and / shall have arithmetic or enumeration type; the operands of % shall have integral or enumeration type. The usual arithmetic conversions are performed on the operands and determine the type of the result.

* 和 / 的操作数应为算术或枚举类型;% 的操作数应为整数或枚举类型。对操作数执行通常的算术转换并确定结果的类型。

The solution is to use fmod, which is exactly why the operands of %are limited to integer type in the first place, according to C99 Rationale§6.5.5 Multiplicative operators:

根据C99 基本原理§6.5.5乘法运算符fmod,解决方案是使用,这正是为什么 的操作数%首先限于整数类型的原因:

The C89 Committee rejected extending the % operator to work on floating types as such usage would duplicate the facility provided by fmod

C89 委员会拒绝将 % 运算符扩展到浮动类型,因为这种用法会重复 fmod 提供的功能

回答by justin

try fmod

尝试 fmod

回答by Andrew

The % operator gives you a REMAINDER(another name for modulus) of a number. For C/C++, this is only defined for integer operations. Python is a little broader and allows you to get the remainder of a floating point number for the remainder of how many times number can be divided into it:

% 运算符为您提供一个数字的 REMAINDER(模数的另一个名称)。对于 C/C++,这仅针对整数运算定义。Python 的范围更广一些,它允许您获取浮点数的余数,求余数的余数可以分为多少次:

>>> 4 % math.pi
0.85840734641020688
>>> 4 - math.pi
0.85840734641020688
>>> 

回答by Shank

The %operator does not work in C++, when you are trying to find the remainder of two numbers which are both of the type Floator Double.

%运算符在 C++ 中不起作用,当您尝试查找两个类型均为Float或 的数字的余数时Double

Hence you could try using the fmodfunction from math.h/ cmath.hor you could use these lines of code to avoid using that header file:

因此,您可以尝试使用/ 中的fmod函数,或者您可以使用这些代码行来避免使用该头文件:math.hcmath.h

float sin(float x) {
 float temp;
 temp = (x + M_PI) / ((2 *M_PI) - M_PI);
 return limited_sin((x + M_PI) - ((2 *M_PI) - M_PI) * temp ));

}

}

回答by Love

"The mathematical notion of modulo arithmetic works for floating point values as well, and this is one of the first issues that Donald Knuth discusses in his classic The Art of Computer Programming (volume I). I.e. it was once basic knowledge."

“模运算的数学概念也适用于浮点值,这是 Donald Knuth 在他的经典计算机编程艺术(第一卷)中讨论的第一个问题。也就是说,它曾经是基础知识。”

The floating point modulus operator is defined as follows:

浮点模运算符定义如下:

m = num - iquot*den ; where iquot = int( num/den )

As indicated, the no-op of the % operator on floating point numbers appears to be standards related. The CRTL provides 'fmod', and usually 'remainder' as well, to perform % on fp numbers. The difference between these two lies in how they handle the intermediate 'iquot' rounding.

如上所述,% 运算符对浮点数的无操作似乎与标准相关。CRTL 提供 'fmod',通常也提供 'remainder',以对 fp 数字执行 %。这两者之间的区别在于它们如何处理中间的“iquot”四舍五入。

'remainder' uses round-to-nearest, and 'fmod' uses simple truncate.

'remainder' 使用舍入到最近,'fmod' 使用简单的截断。

If you write your own C++ numerical classes, nothing prevents you from amending the no-op legacy, by including an overloaded operator %.

如果您编写自己的 C++ 数值类,通过包含重载运算符 %,没有什么能阻止您修改无操作遗留问题。

Best Regards

此致