为什么python除法结果会有小数点0_关于python:为什么整数除法会在许多脚本语言中向下取整?...

在我测试过的语言中,- (x div y )不等于-x div y; 我已经在Python中测试了//,在Ruby中测试了/,在Perl 6中测试了div; C具有类似的行为。

该行为通常是按照规范进行的,因为div通常被定义为除法结果的四舍五入,但是从算术的角度来看,这没有多大意义,因为它使div在 取决于符号的不同方式,这会引起混乱,例如有关如何在Python中完成操作的帖子。

该设计决策背后是否有一些特定的理论依据,还是只是从头开始定义div? 显然,Guido van Rossum在博客文章中使用了一个一致性参数,该参数解释了Python的完成方式,但是如果选择四舍五入,您也可以具有一致性。

(受PMurias在#perl6 IRC频道中提出的问题的启发)

在Python中,FWIW 被称为地板分割。 试试这个:.7 .1。 请注意,它不会计算为int。

FWIW,在Python中,您可以使用双重否定来获得上限划分:例如-(-23 10)

理想情况下,我们希望每个b>0都有两个操作div和mod满足:

(a div b) * b + (a mod b) = a

0 <= (a mod b) < b

(-a) div b = -(a div b)

但是,这在数学上是不可能的。如果以上所有条件都成立,我们将有

1

21 div 2 = 0

1 mod 2 = 1

因为这是(1)和(2)的唯一整数解。因此,到(3),

10 = -0 = -(1 div 2) = (-1) div 2

由(1)表示

1-1 = ((-1) div 2) * 2 + ((-1) mod 2) = 0 * 2 + ((-1) mod 2) = (-1) mod 2

制作与(2)相矛盾的(-1) mod 2 < 0。

因此,我们需要放弃(1),(2)和(3)中的某些属性。

一些编程语言放弃(3),而将div舍入(Python,Ruby)。

在某些(很少)情况下,该语言提供了多个除法运算符。例如,在Haskell中,与Python类似,div,mod仅满足(1)和(2),并且quot,rem仅满足(1)和(3)。后一对运算符将除法舍入为零,以返回负余数为代价,例如,我们有(-1) `quot` 2 = 0和(-1) `rem` 2 = (-1)。

C#也放弃(2),并允许%返回负的余数。连贯地,整数除法向零舍入。从C99开始的Java,Scala,Pascal和C也采用了这种策略。

C#放弃了(2)。 C#中的%运算符不是" mod"运算符。它是"余数"运算符,余数可以为负。

@EricLippert:出于好奇:如果是这种情况,为什么操作员ID字符串为op_Modulus而不是op_Remainder?

@Heinzi:我没有确定的充分理由。这只是很长的小错误列表中的一个,这些小错误并不重要。

只需将方程式的两边都除以零!

浮点运算是由IEEE754定义的,并考虑了数字应用程序,默认情况下,以非常严格定义的方式舍入到最接近的可表示值。

通用国际标准未定义计算机中的整数运算。语言(尤其是C家族的语言)授予的操作倾向于遵循基础计算机提供的任何内容。某些语言比某些语言更健壮地定义某些操作,但是为了避免在当时可用(和流行)的计算机上实现过于困难或缓慢的实现,它们会选择一种非常接近其行为的定义。

因此,整数运算倾向于在溢出时回绕(用于加法,乘法和左移),并且在产生不精确的结果时(用于除法和右移)会向负无穷大舍入。在二进制补码二进制算术中,这两个都是在整数各自的结尾处的简单截断;处理极端情况的最简单方法。

其他答案则讨论了语言与除法运算可能提供的余数或模运算符之间的关系。不幸的是,他们倒退了。余数取决于除法的定义,而不是相反的定义,而模数可以独立于除法定义-如果两个参数碰巧都是正数且除法向下取整,则它们的结果相同,因此人们很少注意到。

大多数现代语言都提供余数运算符或模数运算符,很少会同时提供。库函数可以为关心差异的人们提供其他操作,即余数保留除数的符号,而模数保留除数的符号。

这是一个有趣的观点,也因为您是指模块化算术。如果问题是:"为什么整数除法会在许多脚本语言中取整?",您是否认为相同的答案可能适用?

@iGian好吧,事实是,由于我在答案中概述的原因,大多数语言都无法进行整数除法。通常,他们要么调用CPU DIV指令并只接受它的功能,要么调用实现欧几里得除法的子例程,并且通常执行相同的操作。一个合理的问题可能是"为什么在大多数其他语言都没有的情况下,语言X会四舍五入(或趋近于零,或趋近于零)?" -但您必须指定X,答案将特定于该语言。

那么,许多脚本语言会舍入整数除法,因为CPU DIV基本上是欧几里得除法的实现? ----我很好奇为什么需要四舍五入。您能推荐一种语言X吗?

@iGian就是这样,我不知道一个副手-您是提出它的人。除非另有明确说明,否则有几种方法会默默地将整数操作数强制转换为浮点并执行浮点除法。例如。 BBC BASIC将定义为FP div,将DIV定义为带舍入的整数。 6502甚至没有DIV指令,因此带有子程序。

在C和C ++和Java中,除法向零截断,向右移向负无穷大。

如何处理负无穷大是处理极端情况的最简单方法?为什么不趋向于零或正无穷大或下一个整数?

@ GOTO0我的答案就在那:二进制截断补码算术。具有除法指令的现代CPU通常会这样做,许多软件子例程也会这样做。但是,在子例程中实现它的一种方法是对操作数的正形式执行无符号除法,然后再固定符号。将趋近于零。

事实并非如此:整数除法根本不涉及截断(在所有中间步骤中仅计算整数值)。同样,在x86和类似体系结构上,整数除法指令始终四舍五入为零。

@ GOTO0:"向零"舍入模式的名称是"截断"。例如浮点trunc()函数:en.cppreference.com/w/c/numeric/math/trunc。如果将整数除法视为产生实数的数学除法,然后将其四舍五入为整数,则舍入舍入模式将表示该行为。当然,那不是其在内部实际实施的方式。 BTW,对于算术右移,向-Inf显然是2s补码中最简单的:您只需移入符号位的副本即可得到。

但是这个答案有一个错误。在大多数语言/ ISA中,似乎声称整数除法通常会向-Inf取整。那对于所有具有除法指令的现代CPU体系结构都是不正确的,对于ISO C99和ISO C ++ 11也是不正确的,它们都精确地指定了有符号整数除法舍入语义(以匹配所有现代CPU的功能)。在C ++中使用负数进行整数除法舍入。先前的修订版将其留给实现来选择一种行为(以提高使用不同语义的硬件的效率)。

@PeterCordes:实际上,"截断"仅描述符号幅度表示(例如IEEE-754浮点)中的舍入为零。在二进制补码表示法中,截断实际上是朝着负无穷大舍入,这就是从最有意义的一端转移符号位副本的简单权宜之计。特别是,如果0xFFFF为-1,则0xFFFE为-2。

@Chromatix:啊,我明白了这个术语的意义。但是我的意思是数学截断(en.wikipedia.org/wiki/Truncation),即截断是指将小数点(或二进制)点后的某些位置截断,或者将小数部分去除/归零。截断是数学中的一个术语,不仅仅是计算机科学/工程学,其含义是向零舍入。我认为,不管实现如何,都将舍入为零是最有意义的。 (即使这意味着您不能简单地截断2s补码表示的位。)

Wikipedia在这方面有很棒的文章,包括历史和理论。

只要语言满足(a/b) * b + (a%b) == a的欧几里得除法属性,则地板除法和截断除法都是连贯且在算术上有意义的。

当然,人们喜欢争辩说,一个显然是正确的,而另一个显然是错误的,但它比起明智的讨论更具有圣战的性质,并且通常更多地与选择他们的早期首选语言有关。其他。他们通常也倾向于主要为他们选择的%争论,尽管先选择/然后选择匹配的%可能更有意义。

地板(如Python):

就像唐纳德·克努斯(Donald Knuth)所建议的那样。

%跟随除数的符号显然是大约70%的学生猜测

通常将运算符读取为mod或modulo而不是remainder。

" C做到了" —甚至都不是事实。1

截断(如C ++):

使整数除法与IEEE浮点除法更加一致(在默认的四舍五入模式下)。

更多的CPU实现了它。 (在历史的不同时期可能并非如此。)

运算符被读取为modulo而不是remainder(即使这实际上与他们的观点背道而驰)。

从概念上讲,除法属性更多地是关于余数而不是模量。

运算符被读取为mod而不是modulo,因此应遵循Fortran的区分。 (这听起来很愚蠢,但可能是C99的关键所在。请参阅此线程。)

"欧几里得"(如Pascal- /底数或根据符号截断,因此%永远不会为负):

尼克劳斯·沃思(Niklaus Wirth)认为,没有人对肯定的mod感到惊讶。

雷蒙德·布特(Raymond T. Boute)后来提出,您不能凭借其他任何一条规则天真地实现欧几里得除法。

多种语言都提供。通常,与Ada,Modula-2,一些Lisps,Haskell和Julia一样,它们使用与mod有关的名称(对于Python风格的运算符)和与rem有关的名称对于C ++风格的运算符。但并非总是如此-例如,Fortran调用相同的内容modulo和mod(如上面C99所述)。

我们不知道为什么Python,Tcl,Perl和其他有影响力的脚本语言大多选择地板。正如问题中提到的,Guido van Rossum的答案仅说明了为什么他必须选择三个一致的答案之一,而不是为什么他选择了自己选择的答案。

但是,我怀疑C的影响是关键。大多数脚本语言(至少在最初是用C语言实现的),并从C语言借用其操作员清单。C89的实现定义的%显然已损坏,不适合Tcl或Python之类的"友好"语言。 C将运算符称为" mod"。因此它们采用模数,而不是余数。

1。尽管问题说了什么(很多人都使用它作为参数),但C的行为实际上与Python和其朋友并不相似。 C99需要截断分割,而不是分割。 C89允许使用任一版本,也允许使用任一版本的mod,因此无法保证除法属性,也无法编写具有符号整数除法的可移植代码。真是坏了。 sub>

一些Lisps:Common Lisp定义了mod和rem,请参见lispworks.com/documentation/HyperSpec/Body/f_mod_r.htm和lispworks.com/documentation/HyperSpec/Body/f_floorc.htm

@coredump和其他一些Lisps使用其他名称。 MacLisp只提供了一个,而Racket今天也做同样的事情。 Scheme提供了三个(modulo,remainder,和Wirth样式的mod)。我认为答案不需要与世界上每种语言的方言相关联;说"某些Lips"使用mod / rem样式命名似乎足够了。

因为整数除法的含义是完整答案包括余数。

...而根据定义,其余部分必须始终为正?显然,并非每种语言都适用:在C99中,其余符号与红利符号相同

是的,这是正确的,评论的下限使我发疯!

@jjmerelo在Python中,其余部分(使用%或divmod())始终与除数具有相同的符号。例如123 % -10-> -7

@ SeanFrancisN.Ballais显然只是个惯例问题。维基百科关于模运算的条目说:当a或n为负数时,天真定义会失效,并且编程语言会在定义这些值的方式上有所不同。

正如宝拉(Paula)所说,这是由于剩余的原因。

该算法基于欧几里得除法。

在Ruby中,您可以编写以下代码来重建一致性:

1

2puts (10/3)*3 + 10%3

#=> 10

它在现实生活中的作用相同。 10个苹果和3个人。好的,您可以将苹果切成三等分,但要超出设定的整数。

使用负数时,也保持一致性:

1

2

3puts (-10/3)*3 + -10%3 #=> -10

puts (10/(-3))*(-3) + 10%(-3) #=> 10

puts (-10/(-3))*(-3) + -10%(-3) #=> -10

商总是向下取整(沿负轴向下),并且提示如下:

1

2

3

4

5

6

7

8puts (-10/3) #=> -4

puts -10%3 #=> 2

puts (10/(-3)) #=> -4

puts 10%(-3) # => -2

puts (-10/(-3)) #=> 3

puts -10%(-3) #=> -1

因此,除法和模运算必须是连贯的,这很清楚。但是,您可以选择向上或向下取整,只要这些等式成立,就可以保持连贯性。

@jjmerelo,我同意你的看法,在数学上,您可以选择其他规则,其中# 10 3 = 4 # 10 % 3 = -2 # 3 * 4 - 2 = 10。但这不适用于-2不存在的自然数集。

@iGian您缺少的答案是,有多种方法可以保持负数的一致性而不更改正数的结果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/527556.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux udhcpc指令,dhcpclient和udhcpc区别和用法

udhcpc&#xff1a;1.开发板支持的指令&#xff0c;内核移植时通过make menuconfig打开或关闭,并且需要修改Busybox2.udhcpc只作为客户端使用&#xff0c;服务器指令为udhcpd.3.使用方法-i INTERFACE Interface to use (default: eth0)-r IP IP address to reques…

python求图形面积_求高效的,计算两多边形重叠面积的算法,python实现

[Asm] 纯文本查看 复制代码import random import time from sympy.geometry import * import numpy as np from scipy import stats def polygon_over_area(obj_a, obj_b): p_a obj_a # sympy.geometry.Polygon p_b obj_b x_obj p_a.intersection(p_b) if not x_obj: if p_b…

linux下c代码调用.so,Linux下C程序调用.so(动态链)的一个例子

/*********************************************** 使用Linux下C的动态链接库.So文件* void *pdlHandle;* pdlHandle dlopen("/home/fengsy/len/Len.So/len.so", RTLD_LAZY);* pnswapdlsym(pdlHandle, "swap");****************************************…

dbnetlib sqlserver不存在或拒绝访问_404:对不起,您访问的网页不存在

404&#xff1a;对不起您访问的网页不存在https://www.zhihu.com/video/1101123296195723264你可能在上网时也好奇过&#xff0c;为什么点开一个无法显示信息的页面&#xff0c;上面会出现数字404&#xff1f;要解释这个问题&#xff0c;我们需要从互联网诞生之初说起。20世纪8…

linux中控和安卓中控哪个比较好,原厂中控和改装中控有什么区别?哪个更好?...

很多人都喜欢车辆上有一个大屏的中控。那种大屏的中控不仅功能很多&#xff0c;而且还很实用。但是有很多车需要高配才能有中控。而且还需要加钱。很多人在买车的时候都会选择一些低配的车&#xff0c;然后自己去安装中控。有些人认为原厂的中控不仅价格贵&#xff0c;而且还有…

bufferedreader读取中文乱码_python之pandas模块关于csv文件乱码问题解决

介绍相信部分小伙伴们在处理windows系统生成的csv文件时会遇到中文显示乱码的问题&#xff0c;尤其是使用Excel打开这类文件时这类问题尤为突出。解决如图&#xff0c;我们通过Excel工具打开该csv文件时&#xff0c;中文展示为乱码。此时&#xff0c;只需要我们通过功能强大的数…

linux mint python3.6,Linux 上如何安装并切换最新版本的 Python 3.6

原标题&#xff1a;Linux 上如何安装并切换最新版本的 Python 3.6如果你安装了 Linux 系统&#xff0c;正在学习 Python 并想要使用最新的版本的话&#xff0c;那么这篇文章就是为你而写的。-- ShekinPython是 Linux 中一种最流行的编程语言。它被写成了各种工具和库。除此之外…

centos 卸载软件_Linux服务器运维必备技能 软件包和启动项超详细整理

一、RedHat/CentOS包管理1. 包管理工具RPM(1) 简介最早用在 RedHat的包管理器&#xff0c;现在已经成为Linux常见的包管理系统。RPM包有两种类型&#xff1a;二进制RPM包源码RPM包可以在www.rpmfind.net网站查询软件包&#xff0c;也可以查到其依赖项&#xff1a;(2) RPM包命名…

linux内存分配器类型,内核早期内存分配器:memblock

原标题&#xff1a;内核早期内存分配器&#xff1a;memblock本文转载自Linux爱好者本文来自 程雪涛的自荐投稿Linux内核使用伙伴系统管理内存&#xff0c;那么在伙伴系统工作前&#xff0c;如何管理内存&#xff1f;答案是memblock。memblock在系统启动阶段进行简单的内存管理&…

java substring截取字符串_java基础教程之字符串的介绍,比较重要的一个知识点【下】...

字符串操作1、获取子字符串通过String类的substring()方法可对字符串进行截取。这些方法的共同点就是都是利用字符串的下标进行截取。应明确字符串下标是从0开始的。substring()方法被两种不同的方法重载&#xff0c;来满足不同的需要。(1)substring(intbeginIndex)该方法返回的…

在linux环境下安装wiringpi库,wiringPi库的pwm配置及使用说明

本文介绍树莓派(raspberry pi)在linux c 环境下的硬件pwm配置及使用方法。1. 下载安装wiringPi此步骤建议参考官网指南&#xff0c;wiringPi提供了对树莓派的硬件IO访问&#xff0c;包括GPIO/I2C/PWM等&#xff0c;下载安装后本地会出现wiringPi文件夹&#xff0c;根目录下有/e…

excel split函数_Excel 字符串拆分

用 Excel 处理数据时&#xff0c;有时需要对字符串进行拆分。对于比较简单的拆分&#xff0c;使用 Excel 函数可以顺利完成&#xff0c;但碰到一些特殊需求&#xff0c;或者拆分的规则比较复杂时&#xff0c;则很难用 Excel 实现了。这里列出一些拆分需求示例&#xff0c;分析拆…

python优雅编程_Python优雅地可视化数据

[导读]声明&#xff1a;由于本文的代码大部分是参考书中的例子&#xff0c;所以不提供完整代码&#xff0c;只提供示例片段&#xff0c;也就是只能看出某一部分用法&#xff0c;感兴趣的需要在自己的数据上学习测试。 声明&#xff1a;由于本文的代码大部分是参考书中的例子&am…

linux 未找到wifi适配器,无线 - 重新启动后找不到WI-FI适配器

问题&#xff1a;我已经成功安装了ubuntu 18.04.3 LTS&#xff0c;已经成功连接到无线网络&#xff0c;但是重新启动后&#xff0c;找不到wifi适配器&#xff0c;在每次重新启动时要重新安装wifi驱动程序很烦人&#xff0c;如果能帮帮我&#xff0c;将非常感激&#xff0c;网络…

在c语言中数组下标的最小值,数组元素下标的上限_c语言中,数组元素的下标下限为...

展开全部c语言中&#xff0c;数组元素的下标下限为0。数组中的各元素的存e69da5e887aa62616964757a686964616f31333431373230储是有先后顺序的&#xff0c;它们在内存中按照这个先后顺序连续存放在一起。数组元素用整个数组的名字和它自己在数组中的顺序位置来表示。例如&#…

python求矩形面积_关于python:创建矩形类

我真的不太懂课程&#xff0c;任何帮助都会很好。 矩形类应具有以下私有数据属性&#xff1a; __length __width Rectangle类应该有一个创建这些属性并将其初始化为1的__init__方法。它还应具有以下方法&#xff1a; set_length—此方法为__length字段赋值。 set_width—此方法…

linux epel7安装,在CentOS6.x或CentOS7.x上安装EPEL Repo,Extra Packages for Enterprise Linux (EPEL)...

在CentOS6.x或CentOS7.x上安装EPEL Repo,Extra Packages for Enterprise Linux (EPEL)Error: Cannot retrieve metalink for repository: epel. Please verify its path and try againReporepository&#xff0c;资源库&#xff0c;源的意思。RHEL EPEL(Extra Packages for Ent…

sparkstreaming 读取mysql_第十篇|SparkStreaming手动维护Kafka Offset的几种方式

Spark Streaming No Receivers 方式的createDirectStream 方法不使用接收器&#xff0c;而是创建输入流直接从Kafka 集群节点拉取消息。输入流保证每个消息从Kafka 集群拉取以后只完全转换一次&#xff0c;保证语义一致性。但是当作业发生故障或重启时&#xff0c;要保障从当前…

c语言程序设计题2015,2015年荐C语言程序设计等级考试习题汇编.doc

C语言程序设计等级考试习题汇编1、设计程序&#xff1a;数列第1项为81,此后各项均为它前1项的正平方根&#xff0c;统计该数列前30项之和&#xff0c;并以格式"%.3f"写到考生目录中Paper子目录下的新建文件design.dat中。#include #include void main(){ FILE *p; fl…

用了python之后笔记本卡了_应用

想参与时下最热门的话题讨论吗&#xff1f;看过这些2012最炙手可热的电影电视剧吗&#xff1f;想了解最新职场信息&#xff0c;轻松晋升职场达人么&#xff1f;……本应用为你精选了5个分类(经济、教育、娱乐、生活、科技)共150篇妙趣横生的时尚双语新闻&#xff0c; 7天时间完…