-1%7的结果在javascript(-1)和python(6)中是不同的

时间:2016-12-20 09:44:32

标签: javascript python haskell

JavaScript中的表达式-1正在给我6作为结果。而在Python和Haskell中,我发现结果为{{1}}。

有谁可以解释为什么两者都有不同的行为?哪一个是正确的?

5 个答案:

答案 0 :(得分:6)

我将给出稍微不同的答案。正如其他人所说,功能可以做任何你定义的内容和m mod mod。作为前奏,我会注意到Haskell有两个“mod”函数remmod,它们在这方面有所不同。您可以假设rem一个在数学上更受欢迎。 mod对应于您在x86处理器上获得的内容。事实上,第三个是欧几里德,它可能更好,以及雷蒙德布特在The Euclidean Definitions of the Functions Div and Mod中描述的更好。第三种形式始终返回正模数。 (事实上​​,至少有两个其他选择可以做出。)

因此,Javascript的定义是你从大多数机器x mod m = y mod m操作码得到的。从这个意义上讲,它可能更为可取,因为这样可以使其更有效地实施。在数学上,Haskell和Python的定义比Javascript更好。还有第三个定义可能略好一些。

Euclidean和Haskell / Python定义都拥有的一个关键属性x = y等同于Javascript定义所缺少的m mod 6 % 7。您可以通过在Javascript中计算hbase来验证。

答案 1 :(得分:3)

两者都是正确的。有些语言会返回正模数,而其他语言则保留其符号。

您可以简单地将模数添加到变量中以获得正数,或者在执行模数运算之前检查数字是正数还是负数,并在两者之间切换后更正结果。

在两者之间转换a%b的伪代码:

-1%7 == -1的语言中,您这样做是为了获得正数:

((a%b)+b) % b

使用-1%7 == 6语言,您可以执行此操作以获取签名版本:

if a < 0:
  return (a%b)-b
else:
  return a%b

答案 2 :(得分:3)

两者都是正确的,它们只是对负操作数的处理使用不同的约定。对于正数,约定重合,但对于负数,它们不重合。在Python a % b中,始终与b具有相同的符号。

在下文中,我将使用Python表示法,其中//用于整数除法。

q, r  = a // b, a % b

然后

a == q * b + r

必须在任何语言中均为true(假设ab为整数,b不等于零。因此处理余数的方式必须与用于整数除法的约定一致。在Python中,整数除法是平分,即结果向负无穷大舍入。在一些其他语言中,使用向零舍入。在某些语言中,您可以获得CPU制造商决定实施的任何约定,因此在不同硬件上运行的相同代码可以提供不同的结果。你可以想象,这可能有点烦人。 :)

答案 3 :(得分:1)

两者都是正确的。

要完成其他答案,您还可以考虑Python中的divmod函数:

  

将两个(非复数)数作为参数,并在使用整数除法时返回一对由商和余数组成的数字。对于混合操作数类型,二进制算术运算符的规则适用。对于整数,结果与import multiprocessing as mp import pandas as pd import numpy as np import time import os def just_wait_and_print_len_and_idx(df): """Waits for 5 seconds and prints df length and first and last index""" # Extract some info idx_values = df.index.values first_idx, last_idx = idx_values[0], idx_values[-1] length = len(df) pid = os.getpid() # Waste some CPU cycles time.sleep(1) # Print the info print('First idx {}, last idx {} and len {} ' 'from process {}'.format(first_idx, last_idx, length, pid)) def df_chunking(df, chunksize): """Splits df into chunks, drops data of original df inplace""" count = 0 # Counter for chunks while len(df): count += 1 print('Preparing chunk {}'.format(count)) # Return df chunk yield df.iloc[:chunksize].copy() # Delete data in place because it is no longer needed df.drop(df.index[:chunksize], inplace=True) def main(): # Job parameters n_jobs = 4 # Poolsize size = (10000, 1000) # Size of DataFrame chunksize = 100 # Maximum size of Frame Chunk # Preparation df = pd.DataFrame(np.random.rand(*size)) pool = mp.Pool(n_jobs) print('Starting MP') # Execute the wait and print function in parallel pool.imap(just_wait_and_print_len_and_idx, df_chunking(df, chunksize)) pool.close() pool.join() print('DONE') if __name__ == '__main__': main() 相同。对于浮点数,结果为(a // b, a % b),其中 q 通常为(q, a % b),但可能比该值小1。在任何情况下,math.floor(a / b)都非常接近 a ,如果q * b + a % b非零,则其与 b 具有相同的符号,{{1 }}

a % b

答案 4 :(得分:1)

%代表JavaScript和Python中的不同运算符。

在JavaScript中,%代表Remainder运算符。文档已经指出了余数和模运算之间的区别:

  

当一个操作数除以第二个操作数时,余数运算符返回剩余的余数。它总是采取红利的标志,而不是除数。它使用内置的模数函数来产生结果,这是var1除以var2的整数余数 - 例如 - var1 modulo var2。有人建议在ECMAScript的未来版本中获得一个实际的模运算符,不同之处在于模运算符结果将采用除数的符号,而不是被除数。

(由我强调)

与此相反:在Python中,%代表modulo运算符。文档还对标志做了陈述:

  

%(modulo)运算符从第一个参数除以第二个参数得到余数。数字参数首先转换为通用类型。零右参数会引发ZeroDivisionError异常。 [...] 模运算符总是产生一个与第二个操作数(或零)相同符号的结果;结果的绝对值严格小于第二个操作数的绝对值[2]。

(由我强调)