ฉันจะบังคับให้การหารเป็นจุดลอยตัวได้อย่างไร กองการปัดเศษลงเป็น 0?


721

ฉันมีค่าจำนวนเต็มสองค่าaและb, แต่ฉันต้องการอัตราส่วนในจุดลอย ฉันรู้ว่าa < bฉันและฉันต้องการที่จะคำนวณa / bดังนั้นหากผมใช้จำนวนเต็มส่วนฉันมักจะได้รับ 0 aกับส่วนที่เหลือของ

ฉันcจะบังคับให้เป็นเลขทศนิยมใน Python ได้อย่างไร?

c = a / b

เพียงอัปเกรดเป็น Python 3
Boris

คำตอบ:


807

ใน Python 2 การแบ่งของสอง ints สร้าง int ใน Python 3 มันสร้างทุ่น __future__เราจะได้รับการทำงานใหม่โดยการนำเข้าจาก

>>> from __future__ import division
>>> a = 4
>>> b = 6
>>> c = a / b
>>> c
0.66666666666666663

13
โปรดทราบว่าfrom __future__ import divisionจะต้องอยู่ที่จุดเริ่มต้นของไฟล์
yannis

ปัญหาก็คือถ้าคุณต้องการการหารจำนวนเต็มในที่เดียว แต่การหารแบบลอยตัวในที่อื่นของไฟล์ ...
234192

1
@ mercury0114: ไม่เป็นปัญหา คุณเพียงแค่ใช้//เมื่อคุณต้องการหารชั้นและ/เมื่อคุณต้องการส่วน "true" ( float)
ShadowRanger

715

c = a / float(b)คุณสามารถโยนไปลอยด้วยการทำ ถ้าเศษหรือส่วนเป็นทศนิยมผลลัพธ์ก็จะเป็นเช่นกัน


ข้อแม้: เนื่องจากนักวิจารณ์ได้ชี้ให้เห็นสิ่งนี้จะไม่ทำงานหากbอาจเป็นอย่างอื่นที่ไม่ใช่เลขจำนวนเต็มหรือตัวเลขทศนิยม (หรือสตริงที่แทนหนึ่ง) หากคุณกำลังติดต่อกับประเภทอื่น ๆ (เช่นหมายเลขที่ซับซ้อน) คุณจะต้องตรวจสอบสิ่งเหล่านั้นหรือใช้วิธีการอื่น


195

ฉันจะบังคับให้การแบ่งเป็นทศนิยมใน Python ได้อย่างไร?

ฉันมีค่าจำนวนเต็มสองค่า a และ b แต่ฉันต้องการอัตราส่วนในจุดลอย ฉันรู้ว่า <b และฉันต้องการคำนวณ a / b ดังนั้นถ้าฉันใช้การหารจำนวนเต็มฉันจะได้ 0 ด้วยส่วนที่เหลือของ a

ฉันจะบังคับให้ c เป็นเลขทศนิยมใน Python ได้อย่างไร?

c = a / b

สิ่งที่ถูกถามจริงๆที่นี่คือ:

"ฉันจะบังคับให้เกิดการแบ่งแยกที่แท้จริงได้อย่างไรซึ่งa / bจะคืนเศษส่วน"

อัปเกรดเป็น Python 3

ในหลาม 3 a / bจะได้รับส่วนจริงคุณก็ทำ

>>> 1/2
0.5

การแบ่งชั้นพฤติกรรมการแบ่งแบบคลาสสิกสำหรับจำนวนเต็มอยู่ในขณะนี้a // b:

>>> 1//2
0
>>> 1//2.0
0.0

อย่างไรก็ตามคุณอาจติดขัดโดยใช้ Python 2 หรือคุณอาจจะเขียนโค้ดที่ต้องใช้งานได้ทั้ง 2 และ 3

ถ้าใช้ Python 2

ใน Python 2 มันไม่ง่ายอย่างนั้น วิธีการจัดการกับการแบ่งคลาสสิกไพ ธ อน 2 นั้นดีกว่าและแข็งแกร่งกว่าวิธีอื่น

คำแนะนำสำหรับ Python 2

คุณสามารถรับลักษณะการแบ่ง Python 3 ในโมดูลที่กำหนดด้วยการนำเข้าต่อไปนี้ที่ด้านบน:

from __future__ import division

ซึ่งจะใช้การแบ่งสไตล์ Python 3 กับโมดูลทั้งหมด มันยังใช้งานได้ในเชลล์ไพ ธ อน ณ จุดใดก็ได้ ใน Python 2:

>>> from __future__ import division
>>> 1/2
0.5
>>> 1//2
0
>>> 1//2.0
0.0

นี่เป็นทางออกที่ดีที่สุดเพราะทำให้มั่นใจได้ว่าโค้ดในโมดูลของคุณสามารถใช้งานร่วมกับ Python 3 ได้

ตัวเลือกอื่น ๆ สำหรับ Python 2

หากคุณไม่ต้องการใช้สิ่งนี้กับโมดูลทั้งหมดคุณจะถูก จำกัด การแก้ไขปัญหาเล็กน้อย ความนิยมมากที่สุดคือการบีบบังคับหนึ่งในตัวถูกดำเนินการกับลอย a / (b * 1.0)ทางออกหนึ่งที่มีประสิทธิภาพคือ ใน Python shell สด:

>>> 1/(2 * 1.0)
0.5

ความแข็งแกร่งยังtruedivมาจากoperatorโมดูลoperator.truediv(a, b)แต่อาจช้ากว่าเพราะเป็นการเรียกใช้ฟังก์ชัน:

>>> from operator import truediv
>>> truediv(1, 2)
0.5

ไม่แนะนำสำหรับ Python 2

a / float(b)ปกติเห็นมี สิ่งนี้จะเพิ่ม TypeError ถ้า b เป็นจำนวนเชิงซ้อน เนื่องจากการหารด้วยจำนวนเชิงซ้อนถูกกำหนดมันทำให้ฉันรู้สึกไม่แตกเมื่อหารด้วยจำนวนเชิงซ้อนสำหรับตัวหาร

>>> 1 / float(2)
0.5
>>> 1 / float(2j)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't convert complex to float

มันไม่สมเหตุสมผลสำหรับฉันที่จะทำให้โค้ดของคุณมีความเปราะมากขึ้น

คุณสามารถรัน Python พร้อมกับการ-Qnewตั้งค่าสถานะได้ แต่นี่เป็นข้อเสียของการเรียกใช้งานโมดูลทั้งหมดที่มีการทำงานของ Python 3 ใหม่และโมดูลบางส่วนของคุณอาจคาดหวังว่าการแบ่งแบบคลาสสิกดังนั้นฉันไม่แนะนำสิ่งนี้ยกเว้นการทดสอบ แต่เพื่อแสดงให้เห็น:

$ python -Qnew -c 'print 1/2'
0.5
$ python -Qnew -c 'print 1/2j'
-0.5j

3
"1 // 2 = 0", "1 // 2.0 = 0.0" - gotcha น้อยที่น่าสนใจแม้ว่าจะเป็นการหารจำนวนเต็มถ้าตัวถูกดำเนินการใด ๆ ลอยตัวผลลัพธ์จะเป็นจำนวนเต็ม แต่ก็ลอย ฉันใช้ส่วนจำนวนเต็มเพื่อคำนวณดัชนีรายการและรับข้อผิดพลาดเพราะสิ่งนั้น
อาร์ Navega


66

ใน Python 3.x เครื่องหมายสแลชเดี่ยว ( /) หมายถึงการหารจริง (ไม่ใช่การตัดทอน) เสมอ (ตัว//ดำเนินการใช้สำหรับการตัดทอนส่วน) ใน Python 2.x (2.2 ขึ้นไป) คุณสามารถรับลักษณะการทำงานเดียวกันได้โดยใส่

from __future__ import division

ที่ด้านบนของโมดูลของคุณ


30

เพียงแค่ทำพารามิเตอร์ใด ๆ สำหรับการหารในรูปแบบทศนิยมจะสร้างผลลัพธ์ในทศนิยม

ตัวอย่าง:

>>> 4.0/3
1.3333333333333333

หรือ,

>>> 4 / 3.0
1.3333333333333333

หรือ,

>>> 4 / float(3)
1.3333333333333333

หรือ,

>>> float(4) / 3
1.3333333333333333

4
แต่ในภายหลังคุณอาจถูกล่อลวงให้ทำ1.0 + 1/3หรือfloat(c) + a/bหรือfloat(a/b)คุณจะผิดหวังกับคำตอบ ดีกว่าที่จะใช้ python 3+ หรือนำเข้า__future__.divisionโมดูล (ดูคำตอบที่ยอมรับ) เพื่อรับคำตอบที่คุณคาดหวังเสมอ กฎการแบ่งที่มีอยู่สร้างข้อผิดพลาดทางคณิตศาสตร์ที่ร้ายกาจและยากต่อการติดตาม
เตาแก๊ส

@JoeCondron คุณลองpython -c 'a=10; b=3.0; print a/b'หรือยัง
gsbabil

ฉันไม่ต้องทำเพราะเห็นได้ชัดว่าใช้ได้ในสถานการณ์นี้ อย่างไรก็ตามจะเกิดอะไรขึ้นถ้าaและ 'b' เช่นผลลัพธ์ของฟังก์ชันเลขจำนวนเต็มคืออะไร เช่นa = len(list1), b = len(list2).
JoeCondron

@ JoeCondron: จุดดี float(..)ฉันเพียงแค่ปรับปรุงคำตอบที่จะรวม ฉันคิดว่าการคูณด้วย1.0ตามที่ @Pinochle แนะนำด้านล่างอาจมีประโยชน์เช่นกัน
gsbabil

21

เพิ่มจุด ( .) เพื่อระบุหมายเลขจุดลอยตัว

>>> 4/3.
1.3333333333333333

2
คุณจะใช้วิธีนี้อย่างไรถ้าตัวเศษและส่วนเป็นทั้งสองตัวแปร?
stackoverflowuser2010

ฉันถือว่าคุณอ้างถึงตัวอย่างแรกถ้าเป็นเช่นนั้นฉันจะใช้float()กับหนึ่งในตัวแปร
Alexander

13

สิ่งนี้จะได้ผล

>>> u=1./5
>>> print u
0.2

4
และคุณจะใช้วิธีนี้อย่างไรถ้าตัวเศษและตัวหารเป็นทั้งสองตัวแปร?
stackoverflowuser2010

1
เพราะมันไม่ทำงานเมื่อมีการใช้ตัวแปรสำหรับนามธรรม เกือบจะไม่มีรหัสที่มีความหมายใด ๆ ที่มีค่าฮาร์ดโค้ดเช่นนั้น
Keir Simmons

1
มีคะแนนน้อยเพราะคำตอบนี้ไม่ตอบคำถามและไม่ใช่คำตอบทั่วไป ในคำตอบมันเป็นสิ่งสำคัญเช่นกันก่อนที่จะแสดงว่าเหตุใดจึงใช้งานได้ มันง่ายมาก: ถ้าตัวเศษหรือส่วนเป็นทศนิยมผลลัพธ์จะเป็นทศนิยม โดยปกติแล้วคุณไม่ได้ใช้หลามเป็นเครื่องคิดเลขธรรมดาดังนั้นคุณต้องการคำตอบสำหรับตัวแปรและa b
TimZaman

เป็นเวลานานที่สุดที่ฉันคิดว่า./เป็นผู้ประกอบการที่ถูกต้องในหลามที่ช่วยให้คุณสามารถทำการหารจุดลอยตัว นี่คือเหตุผลว่าทำไมจึงเป็นการดีที่จะใช้พื้นที่สีขาวอย่างรอบคอบในภาษาการเขียนโปรแกรมใด ๆ
smac89

6

หากคุณต้องการใช้การหาร "จริง" (จุดลอยตัว) ตามค่าเริ่มต้นจะมีการตั้งค่าสถานะบรรทัดคำสั่ง:

python -Q new foo.py

มีข้อบกพร่องบางอย่าง (จาก PEP):

มันเป็นที่ถกเถียงกันอยู่ว่าตัวเลือกบรรทัดคำสั่งเพื่อเปลี่ยนค่าเริ่มต้นคือความชั่วร้าย มันอาจเป็นอันตรายในมือที่ไม่ถูกต้อง: ตัวอย่างเช่นมันจะเป็นไปไม่ได้ที่จะรวมแพ็คเกจห้องสมุดบุคคลที่สามที่ต้องการ

คุณสามารถเรียนรู้เพิ่มเติมเกี่ยวกับค่าสถานะอื่น ๆ ที่เปลี่ยน / เตือนเกี่ยวกับพฤติกรรมของการแบ่งโดยดูที่หน้ามนุษย์หลาม

สำหรับรายละเอียดทั้งหมดเกี่ยวกับการเปลี่ยนแปลงการแบ่งอ่าน: PEP 238 - การเปลี่ยนผู้ปฏิบัติงานส่วน


2
from operator import truediv

c = truediv(a, b)

2
แม้ว่ามันจะไม่เหมาะนักเพราะมันไม่ได้ผลในกรณีที่aมี int และbลอย ทางออกที่ดีพร้อมสายเดียวกันคือการทำและการใช้งานแล้วfrom operator import truediv truediv(a, b)
Mark Dickinson

ถูกของคุณ. ฉันสมมุติว่าจำนวนเต็มทั้งสองนี้เป็นเวลาเดียวที่ ops หารแตกต่างกัน แต่คุณต้องการวิธีแก้ปัญหาทั่วไป จริง ๆ แล้วฉันไม่รู้ว่าคุณสามารถนำเข้าโอเปอเรเตอร์หรือไม่สามารถใช้กับ divisors แบบลอยได้ แก้ไขคำตอบแล้ว
JoeCondron

1
from operator import truediv

c = truediv(a, b)

โดยที่ a คือเงินปันผลและ b คือตัวหาร ฟังก์ชั่นนี้มีประโยชน์เมื่อความฉลาดทางหารของจำนวนเต็มสองจำนวนนั้นเป็นทศนิยม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.