ปัดเศษเป็น 5 (หรือหมายเลขอื่น ๆ ) ใน Python


162

มีฟังก์ชั่นในตัวที่สามารถปัดเศษได้ดังต่อไปนี้หรือไม่?

10 -> 10
12 -> 10
13 -> 15
14 -> 15
16 -> 15
18 -> 20

คำตอบ:


304

ฉันไม่รู้เกี่ยวกับฟังก์ชั่นมาตรฐานใน Python แต่มันใช้ได้กับฉัน:

Python 2

def myround(x, base=5):
    return int(base * round(float(x)/base))

Python3

def myround(x, base=5):
    return base * round(x/base)

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

ฉันทำให้ฟังก์ชั่นทั่วไปมากขึ้นโดยให้baseพารามิเตอร์เริ่มต้นที่ 5


3
หากมีเพียงจำนวนเต็มและปัดเศษคุณก็สามารถทำได้x // base * base
Tjorriemorrie

7
นี่คือฉันเป็นคนหวาดระแวง แต่ฉันชอบที่จะใช้floor()และceil()มากกว่าที่จะหล่อ:base * floor(x/base)
user666412

1
@ user666412 math.floorและmath.ceilไม่อนุญาตให้ใช้กับฐานที่กำหนดเองดังนั้นค่ากำหนดจึงไม่เกี่ยวข้อง
คิวเมนตัส

48

สำหรับการปัดเศษเป็นค่าที่ไม่ใช่จำนวนเต็มเช่น 0.05:

def myround(x, prec=2, base=.05):
  return round(base * round(float(x)/base),prec)

ฉันพบว่ามีประโยชน์เนื่องจากฉันสามารถค้นหาและแทนที่ในรหัสของฉันเพื่อเปลี่ยน "round (" เป็น "myround (" โดยไม่ต้องเปลี่ยนค่าพารามิเตอร์)


2
คุณสามารถใช้: def my_round(x, prec=2, base=0.05): return (base * (np.array(x) / base).round()).round(prec) ซึ่งยอมรับอาร์เรย์ numpy เช่นกัน
saubhik

23

มันเป็นเพียงเรื่องของการปรับขนาด

>>> a=[10,11,12,13,14,15,16,17,18,19,20]
>>> for b in a:
...     int(round(b/5.0)*5.0)
... 
10
10
10
15
15
15
15
15
20
20
20

14

การลบส่วนที่เหลือจะทำงานได้:

rounded = int(val) - int(val) % 5

หากค่าเป็นจำนวนเต็ม:

rounded = val - val % 5

ในฐานะที่เป็นฟังก์ชั่น:

def roundint(value, base=5):
    return int(value) - int(value) % int(base)

ฉันชอบคำตอบนี้สำหรับการปัดเศษเป็นค่าเศษส่วนที่ใกล้ที่สุด ie ถ้าฉันต้องการเพิ่มทีละ 0.25 เท่านั้น
jersey bean


9

round (x [, n]): ค่าจะถูกปัดเศษเป็นพหุคูณที่ใกล้เคียงที่สุดของ 10 ถึงกำลังไฟฟ้าลบ n ดังนั้นถ้า n เป็นลบ ...

def round5(x):
    return int(round(x*2, -1)) / 2

ตั้งแต่ 10 = 5 * 2 คุณสามารถใช้การหารจำนวนเต็มและการคูณด้วย 2 แทนการหารและการคูณด้วย 5.0 ไม่ใช่เรื่องที่สำคัญมากเว้นแต่คุณจะชอบการขยับเล็กน้อย

def round5(x):
    return int(round(x << 1, -1)) >> 1

1
+1 สำหรับแสดงให้เราเห็นว่า round () สามารถจัดการการปัดเศษเป็นทวีคูณนอกเหนือจาก 1.0 รวมถึงค่าที่สูงขึ้น ได้ (หมายเหตุอย่างไรก็ตามว่าวิธีบิตขยับจะไม่ทำงานกับลอยไม่พูดถึงมันมากน้อยสามารถอ่านได้โปรแกรมเมอร์ส่วนใหญ่.)
ปีเตอร์แฮนเซน

1
@Peter Hansen ขอบคุณสำหรับ +1 จำเป็นต้องมี int (x) สำหรับการเลื่อนบิตเพื่อทำงานกับโฟลต เห็นด้วยไม่ใช่สิ่งที่อ่านได้มากที่สุดและฉันจะไม่ใช้มันด้วยตัวเอง แต่ฉันชอบ "ความบริสุทธิ์" ของมันเท่านั้นที่เกี่ยวข้องกับ 1 และไม่ใช่ 2 หรือ 5
pwdyson

6

ขออภัยฉันต้องการแสดงความคิดเห็นเกี่ยวกับคำตอบของ Alok Singhai แต่จะไม่ให้ฉันเนื่องจากไม่มีชื่อเสียง = /

อย่างไรก็ตามเราสามารถสรุปอีกหนึ่งขั้นตอนและดำเนินการต่อไป:

def myround(x, base=5):
    return base * round(float(x) / base)

สิ่งนี้ทำให้เราสามารถใช้ฐานที่ไม่ใช่จำนวนเต็มเช่น.25หรือฐานเศษส่วนอื่น ๆ


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

4

เวอร์ชั่น divround ที่แก้ไขแล้ว :-)

def divround(value, step, barrage):
    result, rest = divmod(value, step)
    return result*step if rest < barrage else (result+1)*step

ดังนั้นในกรณีนี้คุณใช้การหาร (ค่า 5, 3)? หรืออาจจะหารด้วย (ค่า 5, 2.5)?
pwdyson

หารด้วยค่า (5, 3)
Christian Hausknecht

4

ใช้:

>>> def round_to_nearest(n, m):
        r = n % m
        return n + m - r if r + r >= m else n - r

มันไม่ได้ใช้การคูณและจะไม่แปลงจาก / เป็นลอย

ปัดเศษเป็นพหุคูณที่ใกล้ที่สุด 10:

>>> for n in range(-21, 30, 3): print('{:3d}  =>  {:3d}'.format(n, round_to_nearest(n, 10)))
-21  =>  -20
-18  =>  -20
-15  =>  -10
-12  =>  -10
 -9  =>  -10
 -6  =>  -10
 -3  =>    0
  0  =>    0
  3  =>    0
  6  =>   10
  9  =>   10
 12  =>   10
 15  =>   20
 18  =>   20
 21  =>   20
 24  =>   20
 27  =>   30

อย่างที่คุณเห็นมันทำงานได้ทั้งจำนวนลบและบวก ความสัมพันธ์ (เช่น -15 และ 15) จะถูกปัดขึ้นเสมอ

ตัวอย่างที่คล้ายกันซึ่งปัดเศษเป็นพหุคูณที่ใกล้เคียงที่สุดของ 5 แสดงให้เห็นว่ามันยังทำงานตามที่คาดไว้สำหรับ "ฐาน" อื่น:

>>> for n in range(-21, 30, 3): print('{:3d}  =>  {:3d}'.format(n, round_to_nearest(n, 5)))
-21  =>  -20
-18  =>  -20
-15  =>  -15
-12  =>  -10
 -9  =>  -10
 -6  =>   -5
 -3  =>   -5
  0  =>    0
  3  =>    5
  6  =>    5
  9  =>   10
 12  =>   10
 15  =>   15
 18  =>   20
 21  =>   20
 24  =>   25
 27  =>   25

2

ในกรณีที่มีคนต้องการ "การปัดเศษทางการเงิน" (0.5 รอบขึ้นไปเสมอ):

def myround(x, base=5):
    roundcontext = decimal.Context(rounding=decimal.ROUND_HALF_UP)
    decimal.setcontext(roundcontext)
    return int(base *float(decimal.Decimal(x/base).quantize(decimal.Decimal('0'))))

ตามเอกสารตัวเลือกการปัดเศษอื่น ๆ ได้แก่ :

ROUND_CEILING (ไปยังอินฟินิตี้),
ROUND_DOWN (ไปยังศูนย์),
ROUND_FLOOR (ไปยัง -Infinity),
ROUND_HALF_DOWN (ใกล้กับความสัมพันธ์ที่ใกล้จะถึงศูนย์),
ROUND_HALF_EVEN (ใกล้กับความสัมพันธ์ที่ใกล้ที่สุดจะเป็นเลขจำนวนเต็ม),
ROUND_HALF_UP ห่างจากศูนย์) หรือ
ROUND_UP (ห่างจากศูนย์)
ROUND_05UP (ห่างจากศูนย์หากตัวเลขหลักสุดท้ายหลังจากปัดเศษเป็นศูนย์จะเป็น 0 หรือ 5 มิฉะนั้นเป็นศูนย์)

โดยค่าเริ่มต้น Python ใช้ ROUND_HALF_EVEN เนื่องจากมีข้อได้เปรียบทางสถิติบางประการ (ผลลัพธ์ที่ได้จะไม่ได้ลำเอียง)


2

สำหรับจำนวนเต็มและ Python 3:

def divround_down(value, step):
    return value//step*step


def divround_up(value, step):
    return (value+step-1)//step*step

การผลิต:

>>> [divround_down(x,5) for x in range(20)]
[0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 10, 10, 10, 10, 10, 15, 15, 15, 15, 15]
>>> [divround_up(x,5) for x in range(20)]
[0, 5, 5, 5, 5, 5, 10, 10, 10, 10, 10, 15, 15, 15, 15, 15, 20, 20, 20, 20]



1

นี่คือรหัส C ของฉัน ถ้าฉันเข้าใจถูกต้องมันควรจะเป็นแบบนี้

#include <stdio.h>

int main(){
int number;

printf("Enter number: \n");
scanf("%d" , &number);

if(number%5 == 0)
    printf("It is multiple of 5\n");
else{
    while(number%5 != 0)
        number++;
  printf("%d\n",number);
  }
}

และสิ่งนี้จะปัดเศษเป็นพหุคูณที่ใกล้เคียงที่สุดแทนการปัดเศษขึ้น

#include <stdio.h>

int main(){
int number;

printf("Enter number: \n");
scanf("%d" , &number);

if(number%5 == 0)
    printf("It is multiple of 5\n");
else{
    while(number%5 != 0)
        if (number%5 < 3)
            number--;
        else
        number++;
  printf("nearest multiple of 5 is: %d\n",number);
  }
}

1

อีกวิธีหนึ่งในการทำสิ่งนี้ (โดยไม่มีการคูณหรือตัวดำเนินการหารอย่างชัดเจน):

def rnd(x, b=5):
    return round(x + min(-(x % b), b - (x % b), key=abs))

-3

คุณสามารถ“เคล็ดลับ” int()เข้าปัดเศษแทนการปัดเศษลงโดยการเพิ่มไปยังหมายเลขที่คุณส่งไป0.5int()


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