วิธีปัดเศษทศนิยม 2 ตำแหน่งด้วย Python อย่างไร


254

ฉันได้รับทศนิยมจำนวนมากในการส่งออกของรหัสนี้ (ฟาเรนไฮต์เพื่อแปลงเซลเซียส)

ขณะนี้รหัสของฉันมีลักษณะเช่นนี้:

def main():
    printC(formeln(typeHere()))

def typeHere():
    global Fahrenheit
    try:
        Fahrenheit = int(raw_input("Hi! Enter Fahrenheit value, and get it in Celsius!\n"))
    except ValueError:
        print "\nYour insertion was not a digit!"
        print "We've put your Fahrenheit value to 50!"
        Fahrenheit = 50
    return Fahrenheit

def formeln(c):
    Celsius = (Fahrenheit - 32.00) * 5.00/9.00
    return Celsius

def printC(answer):
    answer = str(answer)
    print "\nYour Celsius value is " + answer + " C.\n"



main()

ดังนั้นคำถามของฉันคือฉันจะทำให้โปรแกรมปัดเศษทุกคำตอบของทศนิยม 2 ตำแหน่งได้อย่างไร


7
คำพูดเล็ก ๆ เกี่ยวกับรหัสของคุณ ไม่มีเหตุผลที่จะต้องเก็บค่าฟาเรนไฮต์เป็นส่วนกลางมันก็เพียงพอ (และดีกว่า) ในการส่งเป็นพารามิเตอร์ไปยังฟังก์ชั่นของคุณ ดังนั้นลบบรรทัด "global Fahrenheit" ในฟังก์ชัน formeln เปลี่ยนชื่อพารามิเตอร์เป็นฟังก์ชัน "Fahreinheit" formeln (Fahreinheit) สำหรับการปัดเศษคุณสามารถใช้พารามิเตอร์ "%" เพื่อแสดงเฉพาะตัวเลข 2 หลักแรกเท่านั้นและควรปัดเศษสำหรับตัวเลขเหล่านี้ ไม่มีผลต่อจำนวนตัวเลขที่ระบุในสูตรในรูปแบบ
arieli

คำตอบ:


443

คุณสามารถใช้roundฟังก์ชั่นซึ่งใช้เป็นอาร์กิวเมนต์แรกของตัวเลขและอาร์กิวเมนต์ที่สองคือความแม่นยำหลังจากจุดทศนิยม

ในกรณีของคุณมันจะเป็น:

answer = str(round(answer, 2))


21
เรียกว่าการปัดเศษแบงเกอร์ มันหมุนไปทางเลขคู่ มันอยู่ในมาตรฐาน IEEE 754 สำหรับตัวเลขจุดลอย en.wikipedia.org/wiki/Rounding#Round_half_to_even
rolisz

37
ฉันไม่แน่ใจว่าสิ่งใดที่ทำให้ผู้คนโหวตความคิดเห็นข้างต้น สำหรับบันทึกความจริงที่round(2.675, 2)ให้2.67มากกว่า2.68ไม่มีอะไรเกี่ยวข้องกับการปัดเศษของธนาคาร
Mark Dickinson

3
หมายเหตุ : สิ่งนี้จะเปลี่ยนค่าของคำตอบ หากคุณต้องการเพียงแค่รอบสำหรับการแสดงผลให้ไปกับคำตอบของ @Johnsyweb - stackoverflow.com/a/20457284/1498405
hardmooth

4
@Johnsyweb ฉันลองวันนี้ปีหลังโพสต์ต้นฉบับและดูเหมือนว่าจะทำงานตามที่คาดไว้ ดูเหมือนว่า round () วิวัฒนาการมาตามกาลเวลา ดูด้านล่าง: รอบ (1.379, 2) -> 1.38 รอบ (1.372, 2) -> 1.37 รอบ (1.375, 2) -> 1.38
NightFurry

82

ใช้str.format()'s ไวยากรณ์การแสดง answerกับทศนิยมสองตำแหน่ง (โดยไม่ต้องเปลี่ยนค่าพื้นฐานของanswer):

def printC(answer):
    print("\nYour Celsius value is {:0.2f}ºC.\n".format(answer))

ที่ไหน:


3
นี่คือคำตอบที่มีประโยชน์ที่สุด IMO - ช่วยให้มูลค่าที่แท้จริงยังคงอยู่และง่ายต่อการใช้! ขอบคุณ!
BrettJ

ไม่แน่ใจว่าทำไม แต่ '{: 0.2f}'. รูปแบบ (0.5357706) ให้ฉันเป็น '0.54' (python 3.6)
Noam Peled

3
@NoamPeled: ทำไมไม่ควร? 0.5357...อยู่ใกล้0.54กว่า0.53ดังนั้นการปัดเศษให้0.54เข้าท่า
ShadowRanger

"{:0.2f}".format(1.755)-> 1.75 "{:0.2f}".format(1.7551)-> 1.76 - อย่างไรก็ตามฉันคาดว่าทั้งคู่จะเท่ากับ 1.76
Janothan

(เวอร์ชั่น Python: 3.6.10)
Janothan

48

คำตอบส่วนใหญ่ปัญหาหรือround บางครั้งการปัดเศษขึ้นและในกรณีของฉันฉันต้องการค่าของตัวแปรของฉันที่จะปัดเศษลงและไม่เพียงแสดงเช่นนั้นformatround

round(2.357, 2)  # -> 2.36

ฉันพบคำตอบที่นี่: ฉันจะปัดเลขทศนิยมให้เป็นทศนิยมได้อย่างไร

import math
v = 2.357
print(math.ceil(v*100)/100)  # -> 2.36
print(math.floor(v*100)/100)  # -> 2.35

หรือ:

from math import floor, ceil

def roundDown(n, d=8):
    d = int('1' + ('0' * d))
    return floor(n * d) / d

def roundUp(n, d=8):
    d = int('1' + ('0' * d))
    return ceil(n * d) / d

1
ฉัน upvoted - นี่คือสิ่งที่ฉันกำลังมองหา; ฉันชอบงานของคุณกับ python-poloniex: D
Skylar Saveland

2
"ค่าจะถูกปัดเศษเป็นพหุคูณที่ใกล้เคียงที่สุดของ 10 ถึงกำลังลบด้วย ndigits;" docs.python.org/3/library/functions.html#roundดังนั้นไม่รอบไม่เสมอเช่นround(2.354, 2) # -> 2.35
Pete Kirkham

@PeteKirkham คุณถูกต้องฉันแก้ไขคำตอบของฉันเพื่อให้มีเหตุผลและแม่นยำยิ่งขึ้น
s4w3d0ff

2
-0.54 คือคำตอบที่ถูกต้องสำหรับการปัดเศษ -0.5357706 ลงเพราะมันเป็นจำนวนลบ, -0.54 <-0.53
s4w3d0ff

2
ผมจะใช้แทน10**d int('1' + ('0' * d))
Jonathon Reinhart


8

คุณต้องการปัดเศษคำตอบของคุณ

round(value,significantDigit)เป็นทางออกที่สามัญเพื่อทำเช่นนี้อย่างไรก็ตามเรื่องนี้บางครั้งก็ไม่สามารถทำงานได้เป็นหนึ่งคาดหวังจากมุมมองทางคณิตศาสตร์เมื่อหลักรองลงมาทันที (ไปทางซ้ายของ) 5หลักที่คุณกำลังปัดเศษมี

นี่คือตัวอย่างของพฤติกรรมที่คาดเดาไม่ได้:

>>> round(1.0005,3)
1.0
>>> round(2.0005,3)
2.001
>>> round(3.0005,3)
3.001
>>> round(4.0005,3)
4.0
>>> round(1.005,2)
1.0
>>> round(5.005,2)
5.0
>>> round(6.005,2)
6.0
>>> round(7.005,2)
7.0
>>> round(3.005,2)
3.0
>>> round(8.005,2)
8.01

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

>>> round(0.075,2)

0.07

>>> round(0.075+10**(-2*6),2)

0.08

Aha! จากนี้เราสามารถสร้างฟังก์ชัน ...

def roundTraditional(val,digits):
   return round(val+10**(-len(str(val))-1), digits)

โดยทั่วไปสิ่งนี้จะเพิ่มค่าเล็กน้อยให้กับสตริงเพื่อบังคับให้ปัดเศษขึ้นอย่างถูกต้องในอินสแตนซ์ที่ไม่สามารถคาดเดาได้ซึ่งมันไม่ได้มีroundฟังก์ชั่นตามปกติเมื่อคุณคาดหวัง ค่าที่สะดวกในการเพิ่มเป็น1e-Xที่Xเป็นความยาวของสตริงหมายเลขที่คุณกำลังพยายามที่จะใช้ในการบวกround1

วิธีการใช้10**(-len(val)-1)นั้นมีความรอบคอบเนื่องจากเป็นจำนวนน้อยที่สุดที่คุณสามารถเพิ่มเพื่อบังคับให้เปลี่ยนได้ในขณะที่ยังมั่นใจได้ว่าค่าที่คุณเพิ่มจะไม่เปลี่ยนการปัดเศษแม้ว่าทศนิยม.จะหายไป ฉันสามารถใช้เพียงแค่10**(-len(val))มีเงื่อนไขif (val>1)เพื่อลบ1มากกว่า ... แต่มันง่ายกว่าที่จะลบเสมอ1เพราะมันจะไม่เปลี่ยนช่วงจำนวนทศนิยมที่ใช้บังคับวิธีแก้ปัญหานี้สามารถจัดการได้อย่างถูกต้อง วิธีการนี้จะล้มเหลวหากค่าของคุณถึงขีด จำกัด ของประเภทนี้จะล้มเหลว แต่สำหรับเกือบทุกช่วงของค่าทศนิยมที่ถูกต้องที่ควรใช้

ดังนั้นรหัสที่เสร็จแล้วจะเป็นดังนี้:

def main():
    printC(formeln(typeHere()))

def roundTraditional(val,digits):
    return round(val+10**(-len(str(val))-1))

def typeHere():
    global Fahrenheit
    try:
        Fahrenheit = int(raw_input("Hi! Enter Fahrenheit value, and get it in Celsius!\n"))
    except ValueError:
        print "\nYour insertion was not a digit!"
        print "We've put your Fahrenheit value to 50!"
        Fahrenheit = 50
    return Fahrenheit

def formeln(c):
    Celsius = (Fahrenheit - 32.00) * 5.00/9.00
    return Celsius

def printC(answer):
    answer = str(roundTraditional(answer,2))
    print "\nYour Celsius value is " + answer + " C.\n"

main()

... ควรให้ผลลัพธ์ที่คุณคาดหวัง

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


แก้ไข:ขอบคุณBlckknghtสำหรับการชี้ให้เห็นว่า5กรณีที่เกิดขึ้นเฉพาะสวัสดิการค่าบางอย่างที่นี่


6

เพียงใช้การจัดรูปแบบด้วย% .2f ซึ่งจะช่วยให้คุณปัดเศษทศนิยมเป็น 2

def printC(answer):
    print "\nYour Celsius value is %.2f C.\n" % answer

4

คุณสามารถใช้โอเปอเรเตอร์การจัดรูปแบบสตริงของ python "%" "% .2f" หมายถึงตัวเลข 2 หลักหลังจุดทศนิยม

def typeHere():
    try:
        Fahrenheit = int(raw_input("Hi! Enter Fahrenheit value, and get it in Celsius!\n"))
    except ValueError:
        print "\nYour insertion was not a digit!"
        print "We've put your Fahrenheit value to 50!"
        Fahrenheit = 50
    return Fahrenheit

def formeln(Fahrenheit):
    Celsius = (Fahrenheit - 32.0) * 5.0/9.0
    return Celsius

def printC(answer):
    print "\nYour Celsius value is %.2f C.\n" % answer

def main():
    printC(formeln(typeHere()))

main()

http://docs.python.org/2/library/stdtypes.html#string-formatting



3

คุณสามารถใช้ฟังก์ชั่นรอบ

round(80.23456, 3)

จะให้คำตอบ 80.234

ในกรณีของคุณใช้

answer = str(round(answer, 2))

2

หากคุณต้องการหลีกเลี่ยงปัญหาจุดลอยตัวในการปัดเศษตัวเลขสำหรับการบัญชีคุณสามารถใช้รอบ numpy

คุณต้องติดตั้งจำนวนมาก:

pip install numpy

และรหัส:

import numpy as np

print(round(2.675, 2))
print(float(np.round(2.675, 2)))

พิมพ์

2.67
2.68

คุณควรใช้มันหากคุณจัดการเงินด้วยการปัดเศษตามกฎหมาย



1

ไม่แน่ใจว่าทำไม แต่ '{: 0.2f}'. รูปแบบ (0.5357706) ให้ฉันเป็น '0.54' ทางออกเดียวที่ใช้ได้สำหรับฉัน (python 3.6) มีดังต่อไปนี้:

def ceil_floor(x):
    import math
    return math.ceil(x) if x < 0 else math.floor(x)

def round_n_digits(x, n):
    import math
    return ceil_floor(x * math.pow(10, n)) / math.pow(10, n)

round_n_digits(-0.5357706, 2) -> -0.53 
round_n_digits(0.5357706, 2) -> 0.53

นี่คือการตัดทอนไม่ใช่การปัดเศษ
ShadowRanger


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