Bagaimana membulatkan menjadi 2 desimal dengan Python?


254

Saya mendapatkan banyak desimal dalam output kode ini (Fahrenheit to Celsius converter).

Kode saya saat ini terlihat seperti ini:

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()

Jadi pertanyaan saya adalah, bagaimana saya membuat putaran program setiap jawaban ke tempat desimal ke-2?


6
Sebuah komentar kecil tentang kode Anda. Tidak ada alasan untuk membiarkan nilai Fahrenheit disimpan sebagai global, cukup (dan lebih baik) untuk mengirimkannya sebagai parameter ke fungsi Anda. Jadi, hapus baris "global Fahrenheit". Dalam fungsi formeln, ganti nama parameter menjadi fungsi "Fahreinheit" formeln (Fahreinheit). Sedangkan untuk pembulatan, Anda bisa menggunakan parameter "%" untuk hanya menampilkan 2 digit pertama, dan harus dibulatkan untuk digit ini. Tidak ada efek terhadap jumlah digit yang disediakan dalam rumus di formeln.
arieli

Jawaban:


443

Anda dapat menggunakan roundfungsi, yang mengambil sebagai argumen pertama angka dan argumen kedua adalah ketepatan setelah titik desimal.

Dalam kasus Anda, itu akan menjadi:

answer = str(round(answer, 2))


21
Itu disebut pembulatan bankir. Itu bulat menuju angka genap. Ada dalam standar IEEE 754 untuk angka floating point. en.wikipedia.org/wiki/Rounding#Round_half_to_even
rolisz

37
Saya tidak yakin apa yang mendorong orang untuk mengubah komentar di atas. Sebagai catatan, fakta yang round(2.675, 2)memberi 2.67bukannya 2.68tidak ada hubungannya dengan pembulatan Banker.
Mark Dickinson

3
Catatan : ini mengubah nilai jawaban. Jika Anda hanya ingin melihat-lihat, ikuti jawaban @Johnsyweb - stackoverflow.com/a/20457284/1498405
hardmooth

4
@Johnsyweb Saya mencoba hari ini, setahun setelah posting asli dan terlihat berfungsi seperti yang diharapkan. Tampak bulat () berkembang seiring waktu. Lihat di bawah: babak (1,379, 2) -> putaran 1,38 (1,372, 2) -> putaran 1,37 (1,375, 2) -> 1,38
NightFurry

82

Menggunakan str.format()'s sintaks untuk menampilkan answer dengan dua desimal (tanpa mengubah nilai yang mendasari answer):

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

Dimana:

  • :memperkenalkan spesifikasi format
  • 0 memungkinkan tanda-padding nol untuk jenis numerik
  • .2mengatur presisi ke2
  • f menampilkan nomor sebagai nomor titik tetap

3
Ini adalah jawaban IMO yang paling berguna - menjaga nilai aktual tetap dan mudah diterapkan! Terima kasih!
BrettJ

Tidak yakin mengapa, tetapi format '{: 0.2f}' (0,5357706) memberi saya '0,54' (python 3,6)
Noam Peled

3
@NoamPeled: Kenapa tidak? 0.5357...lebih dekat 0.54daripada daripada 0.53, jadi pembulatan menjadi 0.54masuk akal.
ShadowRanger

"{:0.2f}".format(1.755)-> 1,75 "{:0.2f}".format(1.7551)-> 1,76 - Namun, saya berharap keduanya sama dengan 1,76.
Janothan

(Versi Python: 3.6.10)
Janothan

48

Sebagian besar jawaban menyarankan roundatau format. roundkadang-kadang dibulatkan, dan dalam kasus saya, saya perlu nilai variabel saya untuk dibulatkan dan tidak hanya ditampilkan seperti itu.

round(2.357, 2)  # -> 2.36

Saya menemukan jawabannya di sini: Bagaimana cara saya membulatkan angka floating point ke tempat desimal tertentu?

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

atau:

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
Saya terbalik - inilah yang saya cari; Saya suka pekerjaan Anda dengan python-poloniex: D
Skylar Saveland

2
"nilai dibulatkan ke kelipatan terdekat dari 10 ke angka minus daya;" docs.python.org/3/library/functions.html#round jadi tidak, bulat tidak selalu bulat, misalnyaround(2.354, 2) # -> 2.35
Pete Kirkham

@PeteKirkham Anda benar, saya mengedit jawaban saya agar lebih masuk akal dan akurat.
s4w3d0ff

2
-0,54 adalah jawaban yang benar untuk pembulatan -0,5357706 turun karena merupakan angka negatif, -0,54 <-0,53
s4w3d0ff

2
Saya akan menggunakan 10**dsebagai gantinya int('1' + ('0' * d)).
Jonathon Reinhart

11
float(str(round(answer, 2)))
float(str(round(0.0556781255, 2)))

8

Anda ingin melengkapi jawaban Anda.

round(value,significantDigit)adalah solusi biasa untuk melakukan ini, namun ini kadang - kadang tidak beroperasi seperti yang diharapkan dari perspektif matematika ketika angka tersebut langsung lebih rendah (di sebelah kiri) angka yang Anda bulatkan memiliki 5.

Berikut beberapa contoh perilaku yang tidak dapat diprediksi ini:

>>> 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

Dengan asumsi tujuan Anda adalah melakukan pembulatan statistik tradisional dalam sains, ini adalah pembungkus yang berguna untuk membuat roundfungsi berfungsi seperti yang diharapkan membutuhkan importhal-hal tambahan seperti Decimal.

>>> round(0.075,2)

0.07

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

0.08

Aha! Jadi berdasarkan ini kita dapat membuat fungsi ...

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

Pada dasarnya ini menambahkan nilai yang sangat kecil ke string untuk memaksanya untuk mengumpulkan dengan benar pada contoh yang tidak terduga di mana ia biasanya tidak dengan roundfungsi ketika Anda mengharapkannya. Nilai yang nyaman untuk ditambahkan adalah di 1e-Xmana Xpanjang string angka yang Anda coba gunakan roundpada plus 1.

Pendekatan penggunaan 10**(-len(val)-1)itu disengaja, karena jumlah kecil terbesar yang dapat Anda tambahkan untuk memaksa perubahan, sambil juga memastikan bahwa nilai yang Anda tambahkan tidak pernah mengubah pembulatan bahkan jika desimal .hilang. Saya bisa menggunakan hanya 10**(-len(val))dengan persyaratan if (val>1)untuk mengurangi 1lebih banyak ... tapi lebih mudah untuk selalu mengurangi 1karena tidak akan banyak mengubah rentang angka desimal yang dapat diatasi dengan solusi ini. Pendekatan ini akan gagal jika nilai Anda mencapai batas tipe, ini akan gagal, tetapi untuk hampir seluruh rentang nilai desimal yang valid, itu harus bekerja.

Jadi kode yang sudah selesai akan menjadi seperti:

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()

... harus memberi Anda hasil yang Anda harapkan.

Anda juga dapat menggunakan pustaka desimal untuk mencapai hal ini, tetapi pembungkus yang saya usulkan lebih sederhana dan mungkin lebih disukai dalam beberapa kasus.


Sunting: Terima kasih Blckknght untuk menunjukkan bahwa 5kasus pinggiran hanya terjadi untuk nilai-nilai tertentu di sini .


6

Cukup gunakan pemformatan dengan% .2f yang memberi Anda pembulatan menjadi 2 desimal.

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

4

Anda dapat menggunakan operator pemformatan string python "%". "% .2f" berarti 2 digit setelah titik desimal.

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


4

Anda dapat menggunakan operator bulat hingga 2 desimal

num = round(343.5544, 2)
print(num) // output is 343.55

3

Anda dapat menggunakan fungsi putaran.

round(80.23456, 3)

akan memberi Anda jawaban 80.234

Dalam kasus Anda, gunakan

answer = str(round(answer, 2))

Semoga ini membantu :)


2

Jika Anda perlu menghindari masalah floating point pada angka pembulatan untuk akuntansi, Anda dapat menggunakan putaran numpy.

Anda perlu menginstal numpy:

pip install numpy

dan kodenya:

import numpy as np

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

cetakan

2.67
2.68

Anda harus menggunakannya jika Anda mengelola uang dengan pembulatan hukum.


1

Berikut adalah contoh yang saya gunakan:

def volume(self):
    return round(pi * self.radius ** 2 * self.height, 2)

def surface_area(self):
    return round((2 * pi * self.radius * self.height) + (2 * pi * self.radius ** 2), 2)

1

Tidak yakin mengapa, tetapi format '{: 0.2f}' (0,5357706) memberi saya '0,54'. Satu-satunya solusi yang bekerja untuk saya (python 3.6) adalah sebagai berikut:

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

Ini memotong, bukan pembulatan.
ShadowRanger


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.