ปัดเศษตัวเลขทศนิยมให้เป็นจำนวนเต็มที่ใกล้ที่สุด?


128

ตามชื่อเรื่องฉันต้องการหาจำนวนทศนิยมแล้วปัดเศษลงเป็นจำนวนเต็มที่ใกล้ที่สุด อย่างไรก็ตามหากไม่ใช่จำนวนเต็มฉันมักต้องการปัดเศษของตัวแปรไม่ว่าจะใกล้เคียงกับจำนวนเต็มถัดไปเท่าใดก็ตาม มีวิธีทำไหม?


2
ความยากลำบากที่เป็นไปได้คือรูปแบบจุดลอยตัวของ IEEE สามารถแสดงตัวเลขได้มากจนความยิ่งใหญ่มีขนาดใหญ่กว่า 1 ดังนั้นในขณะที่คุณสามารถปัดเศษ x ลงการปัดเศษ x + 1 ลงจะไม่ให้ผลลัพธ์ที่คุณคาดหวัง
dmckee --- อดีตผู้ดูแลลูกแมว

กรุณาโพสต์ตัวอย่างบางส่วน
Ashwini Chaudhary

คำตอบ:


179

ง่าย

print int(x)

จะทำงานเช่นกัน


7
int (0.6) = 0 แทนที่จะเป็น 1
Helin Wang

39
@HelinWang นั่นคือสิ่งที่ OP ขอ
Petr Peller

5
นี่ดูเหมือนวิธี Pythonic มากที่สุด
Gyan Veda

23
สิ่งนี้ใช้ได้ดีกับจำนวนบวก แต่จำนวนลบจะถูกปัดขึ้น:int(-23.3) == 23
Alex Riley

2
และไม่ทำงานสำหรับตัวเลขที่เกินช่วงจำนวนเต็มเช่น 600851475143 โดยทั่วไปจะตั้งค่าสถานะข้อผิดพลาดของหน่วยความจำ
Muyide Ibukun

77

หนึ่งในนั้นควรใช้งานได้:

import math
math.trunc(1.5)
> 1
math.trunc(-1.5)
> -1
math.floor(1.5)
> 1
math.floor(-1.5)
> -2

14
ผลลัพธ์จากmath.truncเป็นจำนวนเต็มในขณะที่ผลลัพธ์ของmath.floorเป็นทศนิยม
evedovelli

6
@evedovelli: ไม่จริงอีกต่อไป type(math.floor(1.51)) -> intและtype(math.trunc(1.51)) -> intณ วันที่python 3.6.0
SKPS

4
ตัวเลือกเหล่านี้มีความชัดเจนมากกว่า "int (x)" และด้วยเหตุนี้จึงมี Pythonic มากกว่า
Tristan

44
x//1

ตัว//ดำเนินการส่งคืนพื้นของการหาร เนื่องจากการหารด้วย 1 ไม่ได้ทำให้ตัวเลขของคุณเปลี่ยนไปจึงเทียบเท่ากับขั้นต่ำ แต่ไม่จำเป็นต้องนำเข้า หมายเหตุ:

  1. สิ่งนี้ส่งคืนค่าลอย
  2. รอบนี้ไปทาง-∞

นอกจากนี้ยังดี int(-1.1) == -1ในขณะที่-1.1//1 == -2.0อย่างไรก็ตามdecimal.Decimal('-1.1')//1 == decimal.Decimal('-1')(ตามเอกสารอ้างว่า 2 ไม่เป็นความจริงสำหรับdecimal) ดังนั้นการพึ่งพา//พฤติกรรมจึงไม่คงที่อย่างสมบูรณ์แม้ในปัจจุบัน
Tino

28

ในการรับผลลัพธ์ทศนิยมให้ใช้:

round(x-0.5)

มันใช้ได้กับจำนวนลบเช่นกัน


6
ซับซ้อนมากนั่นคือ
Alon


9

หลายคนบอกว่าให้ใช้int(x)และมันก็ใช้ได้สำหรับกรณีส่วนใหญ่ แต่มีปัญหาเล็กน้อย หากผลของ OP คือ:

x = 1.9999999999999999

มันจะปัดเศษเป็น

x = 2

หลังจากวันที่ 16 9 จะออกรอบ นี่ไม่ใช่เรื่องใหญ่หากคุณแน่ใจว่าจะไม่มีวันเจอเรื่องแบบนี้ แต่เป็นสิ่งที่ควรคำนึงถึง


17
นั่นเป็นเพราะ1.9999999999999999จริง ๆ แล้วเท่ากับ2.0ในการแสดง float64 ภายใน I. จ. มันถูกปัดเศษทันทีที่แยกวิเคราะห์เป็นทศนิยมเนื่องจากทศนิยม 64 บิตไม่สามารถแสดงตัวเลขที่มีนัยสำคัญจำนวนมากได้ 1.9999999999999999 == 2.0คุณสามารถตรวจสอบได้ว่ามีการประเมิน และหากคุณสงสัยว่าการดำเนินการเท่ากับทำการปัดเศษบนโฟลตคุณสามารถเปรียบเทียบการแทนค่าไบนารีstruct.pack("d", 1.9999999999999999) == struct.pack("d", 2.0)ซึ่งมีค่าเท่ากันได้เช่นกัน
blubberdiblub

4
int()และถ้าเกิดว่าตรงจุดของคุณแล้วผมไม่เห็นอะไรผิดปกติกับ ค่าเป็น 2.0 แล้วและจะแปลงเป็น 2 อย่างมีความสุข
blubberdiblub

1
หาก OP (หรือใครก็ตามอ่านสิ่งนี้ในอนาคต) มีเจตนาที่จะใช้จำนวนเต็มที่ใกล้ที่สุด (ไม่ใช่ค่าปัดเศษ) ไม่ว่าด้วยเหตุผลใดก็เป็นสิ่งที่ควรคำนึงถึง
lokilindo

3
@lokilindo แต่สิ่งนี้int()ไม่เกี่ยวข้องกับการใช้งานที่ไม่เหมาะสมfloatเท่านั้นเนื่องจาก1.9999999999999999จะปัดเศษขึ้น2.0 ในเวลาคอมไพล์ (ในขณะที่int()เรียกว่าเวลาดำเนินการ) หากคุณใช้ประเภทข้อมูลที่ถูกต้องสำหรับตัวแปรทุกอย่างจะทำงานได้ตามที่คาดไว้: int(decimal.Decimal('1.9999999999999999999999999999999999999999999999999999999'))ให้1
Tino

6

หากคุณไม่ต้องการนำเข้าคณิตศาสตร์คุณสามารถใช้:

int(round(x))

นี่คือส่วนหนึ่งของเอกสาร:

>>> help(round)
Help on built-in function round in module __builtin__:

round(...)
    round(number[, ndigits]) -> floating point number

    Round a number to a given precision in decimal digits (default 0 digits).
    This always returns a floating point number.  Precision may be negative.

ขอบคุณสำหรับคำตอบ. ครั้งต่อไปคุณจะได้รับการต้อนรับที่ดีขึ้นหากคุณเขียนโค้ดที่ถูกต้อง (วงเล็บปิด) และให้เอกสารประกอบ
Geoff

2
roundมีการพูดคุยและปฏิเสธเป็นคำตอบเมื่อมีการถามคำถามนี้เมื่อปีที่แล้ว math.floorต้องการ OP
Adam Smith

3

หากคุณทำงานกับ numpy คุณสามารถใช้วิธีแก้ปัญหาต่อไปนี้ซึ่งใช้ได้กับจำนวนลบเช่นกัน (มันทำงานกับอาร์เรย์ด้วย)

import numpy as np
def round_down(num):
    if num < 0:
        return -np.ceil(abs(num))
    else:
        return np.int32(num)
round_down = np.vectorize(round_down)

round_down([-1.1, -1.5, -1.6, 0, 1.1, 1.5, 1.6])
> array([-2., -2., -2.,  0.,  1.,  1.,  1.])

ฉันคิดว่ามันจะใช้ได้เช่นกันถ้าคุณใช้mathโมดูลแทนnumpyโมดูล


1

ไม่ทราบว่าคุณแก้ไขได้หรือไม่ แต่ฉันเพิ่งสะดุดกับคำถามนี้ หากคุณต้องการกำจัดจุดทศนิยมคุณสามารถใช้ int (x) และมันจะกำจัดหลักทศนิยมทั้งหมด ไม่จำเป็นต้องใช้ round (x)


1

เพียงแค่ทำรอบ (x-0.5) สิ่งนี้จะส่งกลับค่าจำนวนเต็มที่ปัดลงถัดไปของ Float ของคุณเสมอ คุณยังสามารถปัดเศษขึ้นได้อย่างง่ายดายโดยทำรอบ (x + 0.5)


-1

มันอาจจะง่ายมาก แต่คุณปัดมันขึ้นมาแล้วลบ 1 ไม่ได้เหรอ? ตัวอย่างเช่น:

number=1.5
round(number)-1
> 1

4
สิ่งนี้ให้คำตอบที่ผิดสำหรับจำนวนเต็ม ตัวอย่างเช่น 2.0 ปัดเศษขึ้นเป็น 2 และหากคุณลบ 1 คุณจะได้ผลลัพธ์ที่ไม่ถูกต้อง 1.
Pascal Cuoq

@PascalCuoq ฉันไม่เข้าใจปัญหาของคุณ คุณต้องการ 1.0 เป็นผลลัพธ์หรือไม่? เพราะ OP integerต้องการอย่างชัดเจนไปยังหมายเลขแล้วรอบออกไปที่ใกล้ที่สุด
bad_keypoints

1
@bad_keypoints ฉันไม่คิดว่า OP ต้องการรอบ 2.0 ถึง 1
Pascal Cuoq

@PascalCuoq ขออภัยฉันเพิ่งย้อนกลับไปดูคำตอบในชุดความคิดเห็นที่เราเป็น
bad_keypoints

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