是否有一种语言定义模零余数等于被除数?为什么这样定义它并不常见?

发布于 2024-10-31 08:55:04 字数 562 浏览 10 评论 0原文

考虑整数除法:

a = bq + r

其中 abq< /i>、r分别是:被除数、除数、商、余数。特别是当 b = 0 时,没有唯一的 q 满足给定 a 的方程,因此商 <在这种情况下,i>q 应该是未定义的。

然而,在这种情况下确实存在唯一的r,即r = a。在商和余数总是一起定义的前提下,只要q未定义,那么r就没有定义,但在编程中,我们经常想使用余数运算%/ 划分无关。我实际上遇到过一种情况,我想要 if b == 0 then a else a % b end

任何编程语言中是否有一个运算符与 % 相同,但当除数为 0 时返回被除数而不是零除错误?

大多数(或所有)编程语言返回 % 0 的零除错误有什么原因吗?

Consider integer division:

a = bq + r

where a, b, q, r are respectively: dividend, divisor, quotient, and remainder. Particularly when b = 0, there is no unique q that satisfies the equation for a given a, and hence it makes sense that the quotient q should be undefined in such case.

However, there is indeed a unique r in such case, namely, r = a. Under the premise that the quotient and the remainder are always defined together, it would follow that r is not defined whenever q is undefined, but in programming, we often want to use the remainder operation % irrespective of division /. I actually came across a situation where I want if b == 0 then a else a % b end.

Is there/Was there an operator in any programming language such that it is the same as % but returns the dividend instead of a zero division error when the divisor is 0?

Is there any reason that most (or all) programming languages return a zero division error for % 0?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

千柳 2024-11-07 08:55:04

从数学上来说,余数介于 0 和 b-1 之间,其中 b 是除数。因此,当 b = 0 时,r 未定义,因为它必须 >= 0。

Mathematically, the remainder is between 0 and b-1, where b is the divisor. Therefore, when b = 0, r is undefined since it has to be >= 0.

滴情不沾 2024-11-07 08:55:04

有没有一种编程语言能够带来红利?没有把握。我从来没有遇到过。

大多数人不返还股息有什么原因吗? 。模数是 CS 中的常见运算,因为它是 CPU 上整数除法的副产品。大多数(如果不是全部)汇编语言都有模数运算,并且该运算使用与除法运算完全相同的硬件。因此,如果你不能在硬件中除以零,那么你就不能在硬件中进行模零运算。

这是否意味着您不能拥有支持此功能的语言?并非如此,但您必须将 if 语句添加到通常是单个指令的操作中。这可能会导致相当严重的性能损失,所以很少(如果有的话)这样做。

Is there any programming language that returns the dividend? Not sure. I've never come across any.

Is there a reason that most don't return the dividend? Yes. Modulus is a common operation in CS because it is a byproduct of integer division on a CPU. Most (if not all) assembly languages have a modulus operation, and this operation uses the exact same hardware as the division operation. Thus if you can't divide by zero in hardware, then you can't do modulus zero in hardware.

Does this mean that you can't have a language that supports this? Not really, but you would have to add an if-statement to an operation that is usually a single instruction. This would probably result in a pretty heavy performance hit, so few (if any) do it.

对你再特殊 2024-11-07 08:55:04

我知道定义整数除法余数的三个来源,使其与您的观察结果一致:

  • Donald Knuth in 计算机编程的艺术,第 1 卷 (1969) (§1.2.4,第 14 页)。 38) 定义 x mod 0 等于 x。对于非零除数,它被定义为地板除法的余数: a mod b := ab × ⌊a ÷ b⌋。 Knuth、Ronald Graham 和 Oren Patashnik 在《具体数学》中重复了这个定义。

  • APL\1130 手册(也是 1969 年) (p. 57) 定义了一个名为“residue”的操作 |,用于与 Raymond Boute 的论文 称为“E 定义”,而对于零除数,它返回被除数,但前提是后者非负;否则,这是一个域错误。

    “残差”的基本数学定义似乎是

    <块引用>

    b|a := inf { x ≥ 0 : ∃ c ∈ ℤ: a − < i>x = b c }

    对于负 a 和零 b 将是 inf ∅ = ∞,我认为无法表示。

  • 在 RISC-V 指令集中,“M”扩展名 (RISC-V指令集手册,第一卷,版本20191213,§7.2,第45页,表7.1)定义了除以零时返回被除数的余数指令;相应的除法指令返回所有位都设置为 1 的值(有符号除法为 -1,无符号除法为最大可能的字值)。

无符号长除法算法的简单实现也将与 RISC-V 除法和余数的定义一致,假设余数可以在目标变量(和所有中间变量)中表示,而不会溢出。

为什么以这种方式定义余数不更常见?我想说这更多地与实际考虑有关,而不是与数学考虑有关。余数通常被认为是除法的副产品,而不是本身就是环同态;这两个操作通常也使用计算两个结果的通用指令来实现。由于除以零是未定义的,因此许多体系结构选择它来捕获(触发异常)这种情况,包括流行的 x86。这意味着余数操作也会陷入困境。较高级别的语言很少愿意覆盖此选择,原因有很多:

  • 根本不考虑这个问题,因为合法出现余数为零的情况很少见,并且乍一看引发异常似乎是合理的选择;
  • 不愿意通过额外的除数检查来增加实现的负担;
  • 不愿意偏离类似的编程语言。

I know of three sources defining remainder of integer division such that it agree with your observation:

  • Donald Knuth in The Art of Computer Programming, Volume 1 (1969) (§1.2.4, p. 38) defines x mod 0 to equal x. For nonzero divisors it is defined as the remainder of flooring division: a mod b := ab × ⌊a ÷ b⌋. This definition is repeated in Concrete Mathematics by Knuth, Ronald Graham and Oren Patashnik.

  • The APL\1130 manual (also 1969) (p. 57) defines an operation | named “residue”, for non-zero divisors defined consistently with what Raymond Boute’s paper calls the “E-definition”, while for the zero divisor it returns the dividend, but only if the latter is non-negative; it is a domain error otherwise.

    It appears that the underlying mathematical definition of “residue” is

    b|a := inf { x ≥ 0 : ∃ c ∈ ℤ: ax = b c }

    which for negative a and zero b would have been inf ∅ = ∞, which I assume cannot be represented.

  • In the RISC-V instruction set, the “M” extension (RISC-V Instruction Set Manual, Volume I, Version 20191213, §7.2, p. 45, table 7.1) defines the remainder instructions to return the dividend in case of division by zero; the corresponding division instructions return the value with all bits set to 1 (−1 for signed division, the largest possible word value for unsigned division).

A naïve implementation of the unsigned long division algorithm will also agree with the RISC-V definition of division and remainder, assuming the remainder can be represented in the destination variable (and all intermediaries) without overflow.

Why is it not more common to define remainder-by-zero this way? I’d say it has more to do with practical, rather than mathematical, considerations. Remainder is commonly thought of as a by-product of division rather than a ring homomorphism in its own right; both operations are also usually implemented with a common instruction that computes both results. Since division by zero is undefined, many architectures choose it to trap (trigger an exception) in this situation, including the popular x86. Which means the remainder operation is going to trap as well. Languages at a higher level are rarely willing to override this choice, for a number of possible reasons:

  • not considering the issue at all, since situations in which remainder-by-zero legitimately appears are rare and raising an exception seems at first glance a reasonable choice;
  • reluctance to burden implementations with extra divisor checks;
  • reluctance to diverge from similar programming languages.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文