Beberapa angka desimal tidak dapat secara tepat direpresentasikan sebagai pelampung biner karena representasi internal pelampung biner. Sebagai contoh: pembulatan 14.225 ke dua angka desimal tidak menghasilkan 14.23 seperti yang diharapkan, tetapi dalam 14.22.
Python :
In: round(14.225, 2)
Out: 14.22
Asumsikan, bagaimanapun, bahwa kita memiliki representasi string 14.225 sebagai '14 .225 ', kita harus dapat mencapai pembulatan yang kita inginkan '14 .23' sebagai representasi string.
Pendekatan ini dapat digeneralisasi ke presisi sewenang-wenang.
Kemungkinan Solusi Python 2/3
import sys
def round_string(string, precision):
assert(int(precision) >= 0)
float(string)
decimal_point = string.find('.')
if decimal_point == -1:
if precision == 0:
return string
return string + '.' + '0' * precision
all_decimals = string[decimal_point+1:]
nb_missing_decimals = precision - len(all_decimals)
if nb_missing_decimals >= 0:
if precision == 0:
return string[:decimal_point]
return string + '0' * nb_missing_decimals
if int(all_decimals[precision]) < 5:
if precision == 0:
return string[:decimal_point]
return string[:decimal_point+precision+1]
sign = '-' if string[0] == '-' else ''
integer_part = abs(int(string[:decimal_point]))
if precision == 0:
return sign + str(integer_part + 1)
decimals = str(int(all_decimals[:precision]) + 1)
nb_missing_decimals = precision - len(decimals)
if nb_missing_decimals >= 0:
return sign + str(integer_part) + '.' + '0' * nb_missing_decimals + decimals
return sign + str(integer_part + 1) + '.' + '0' * precision
Penggunaan :
# No IEEE 754 format rounding
In: round_string('14.225',2)
Out: '14.23'
# Trailing zeros
In: round_string('123.4',5)
Out: '123.40000'
In: round_string('99.9',0)
Out: '100'
# Negative values
In: round_string('-99.9',0)
Out: '-100'
In: round_string('1',0)
Out: '1'
# No unnecessary decimal point
In: round_string('1.',0)
Out: '1'
# No unnecessary decimal point
In: round_string('1.0',0)
Out: '1'
In: for i in range(8):
print(round_string('123456789.987654321',i))
Out: 123456790
123456790.0
123456789.99
123456789.988
123456789.9877
123456789.98765
123456789.987654
123456789.9876543
Tugas
Argumen input 1 : string yang berisi
- setidaknya satu digit (
0
,1
,2
,3
,4
,5
,6
,7
,8
,9
), - paling banyak satu titik desimal (
.
) yang harus didahului oleh setidaknya satu digit, - minus opsional (
-
) sebagai karakter pertama.
Argumen masukan 2 : bilangan bulat non-negatif
Output : string yang dibulatkan dengan benar (basis 10)
pembulatan = Membulatkan setengah dari nol
Ini adalah kode-golf . Jumlah byte terendah menang!
round(A,B
5 byte0
bukan bilangan bulat positif, itu "non-negatif".123.4 & 5 --> 123.40000
? Atau dapatkah kita berasumsi bahwa input kedua tidak akan pernah lebih besar dari jumlah desimal setelah titik pada input pertama?Jawaban:
APL (Dyalog) , 4 byte
Dyalog APL menggunakan presisi internal yang cukup.
Cobalah online!
⍎⍞
jalankan input string⎕⍕
dapatkan input numerik dan gunakan itu sebagai presisi untuk pemformatansumber
Perl,
2220 byteMenggunakan:
Ini adalah versi kode Dada. Sebelumnya:
sumber
printf"%.*f",pop,pop
harus bekerjaPHP,
3331 bytePutaran PHP dengan benar juga (setidaknya pada 64 bit):
mengambil input dari argumen baris perintah. Jalankan dengan
-r
.PHP, tanpa built-in, 133 byte
Jalankan dengan
-nr
atau coba online .kerusakan
Bita nol tidak berfungsi; jadi saya harus menggunakan
substr
.sumber
"%.$argv[2]f"
alih-alih"%.{$argv[2]}f"
, menghemat 2 byte.Ruby 2.3, 12 + 45 = 57
Menggunakan
BigDecimal
built-in, tetapi harus diperlukan sebelum digunakan, yang lebih murah untuk dilakukan sebagai flag.bendera:
-rbigdecimal
fungsi:
Ruby 2.3 secara default menggunakan
ROUND_HALF_UP
sumber
Javascript (ES6), 44 byte
Cobalah online:
sumber
Python,
114105103969189 byteDisimpan 5 byte berkat Kevin Cruijssen
Disimpan 2 byte berkat Krazor
Cobalah online!
sumber
from decimal import *
dan menghapus ketiganyad.
adalah 4 byte lebih pendek.d=Decimal
dand()
, yang akan menyelamatkan 5. lainnya (Mungkin salah, sangat mengantuk)REXX, 24 byte
Karena REXX selalu menggunakan representasi teks angka, pembulatan angka yang benar adalah gratis.
Cobalah online!
sumber
BASH,
262321 bytepemakaian
simpan ke round_string.sh, chmod + x round_string.sh
sunting: tidak perlu memuat perpustakaan
sumber
14.22
input14.225 2
, dan bukan14.23
AHK, 25 byte
Sekali lagi saya digagalkan oleh ketidakmampuan AHK untuk menggunakan parameter yang diteruskan secara langsung dalam fungsi yang menerima baik nama variabel atau nomor. Jika saya ganti
a
dengan1
dalamRound
fungsi, ia menggunakan nilai1
. Jika saya mencoba%1%
, mencoba untuk menggunakan argumen pertama isi sebagai nama variabel, yang tidak bekerja. Setelah menetapkannya sebagai variabel lain, biayanya 6 byte.sumber
Batch, 390 byte
Penjelasan. Mulai dengan mengekstraksi tanda, jika ada. Kemudian, bagi angka menjadi bilangan bulat dan pecahan. Fraksi ini diisi dengan
n+1
nol untuk memastikan memiliki lebih darin
digit. Then
th (zero-diindeks) digit dibagi oleh 5, dan ini adalah carry awal. Angka integer dann
fraksi digabungkan, dan carry ditambahkan karakter demi karakter. (Nol ekstra melindungi dari bawa riak.) Setelah carry berhenti, riak nomor direkonstruksi dan titik desimal apa pun dimasukkan.sumber
TI-Basic,
5316 byteTI-Basic tidak menggunakan IEEE dan metode di bawah ini berfungsi untuk posisi desimal 0-9 (inklusif).
Terima kasih kepada @JulianLachniet karena menunjukkan bahwa CE calcs memiliki
toString(
perintah yang tidak saya ketahui (Color Edition calcs OS 5.2 atau lebih tinggi diperlukan).PS Saya memang memiliki baris kedua dengan
sub(Str1,1,N+inString(Str1,".
tetapi kemudian saya menyadari itu tidak berguna.sumber
N
digunakan?Java 7,
777271 byte-1 byte terima kasih kepada @cliffroot
Jawaban 72 byte:
Tidak seperti Python, Java sudah bulat dengan benar dan sudah mengembalikan String ketika Anda menggunakan
String.format("%.2f", aDouble)
dengan2
jumlah desimal yang Anda inginkan.EDIT / CATATAN: Ya, saya sadar
new Float(n)
1 byte lebih pendek darinew Double(n)
, tetapi ternyata gagal untuk kasus uji dengan123456789.987654321
. Lihat kode tes ini tentang Double vs Float.Penjelasan:
Kode uji:
Coba di sini.
Keluaran:
sumber
<T>T c(T n,int d){return(T)"".format("%."+d+"f",new Double(n+""));}
123456789.987654321, 4
seharusnya123456789.9877
, tidak123456789.9876
Python (2/3), 394 byte
Berfungsi untuk angka presisi yang berubah-ubah.
sumber
s[0]<'0'
dan juga bisa menggunakan string multiplikasim='-'*(s[0]<'0')
,. Baris tanpa bentang pernyataan blok dapat digabungkan bersama;
(misalnyao='';c=0
). Beberapaif
pernyataan mungkin dapat diganti dengan pengindeksan daftar untuk lebih mengurangi kebutuhan akan jeda baris dan tab. Baris terakhir bisa menggunakan irisano[::-1]
,, bukanreversed(o)
dan''.join
itu berlebihan. Anda mungkin juga dapat menulis ulang untuk menghindari kebutuhan akan banyakreturn
pernyataan.JavaScript (ES6), 155 byte
Penjelasan: String pertama kali dinormalisasi untuk mengandung digit a
.
dann+1
desimal. The digit trailing, setiap sebelumnya9
s atau.
s, dan setiap digit sebelumnya, kemudian dipertimbangkan. Jika digit terakhir kurang dari 5 maka digit tersebut dan setiap yang sebelumnya segera.
dihapus, tetapi jika lebih besar dari 5 maka9
s diubah menjadi0
s dan digit sebelumnya bertambah (atau 1 diawali jika tidak ada digit sebelumnya).sumber
Python 3 + SymPy, 54 byte
Cobalah online!
sumber
Scala, 44 byte
Uji:
sumber
Bertanya-tanya , 10 byte
Pemakaian:
Atur presisi desimal dan tambahkan nol tambahan jika perlu.
sumber
npm i -g wonderlang
. Gunakanwonder
perintah untuk menjalankan REPL, dan tempel kode.J,
2217 byteTerima kasih kepada @Conor O'Brien karena mengoreksi pemahaman saya tentang aturan.
sumber
2 t '1234.456'
harus memberikan1234.46
bukannya6 t '1234.456'