Niektórych liczb dziesiętnych nie można dokładnie przedstawić jako liczb binarnych ze względu na wewnętrzną reprezentację liczb binarnych. Na przykład: zaokrąglenie 14,225 do dwóch cyfr dziesiętnych nie daje 14,23, jak można się spodziewać, ale 14,22.
Python :
In: round(14.225, 2)
Out: 14.22
Załóżmy jednak, że mamy ciąg znaków reprezentujący 14,225 jako „14,225”, powinniśmy być w stanie osiągnąć pożądane zaokrąglenie „14,23” jako ciąg znaków.
To podejście można uogólnić z dowolną precyzją.
Możliwe rozwiązanie 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
Zastosowanie :
# 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
Zadanie
Argument wejściowy 1 : ciąg zawierający
- co najmniej jedna cyfra (
0
,1
,2
,3
,4
,5
,6
,7
,8
,9
) - co najwyżej jedna kropka dziesiętna (
.
), która musi być poprzedzona co najmniej jedną cyfrą, - opcjonalny minus (
-
) jako pierwszy znak.
Argument wejściowy 2 : nieujemna liczba całkowita
Wyjście : poprawnie zaokrąglony ciąg (podstawa 10)
zaokrąglenie = zaokrąglić w połowie od zera
To jest golf golfowy . Najmniejsza liczba bajtów wygrywa!
round(A,B
5 bajtów0
nie jest dodatnią liczbą całkowitą, jest „nieujemny”.123.4 & 5 --> 123.40000
? Czy możemy założyć, że drugie wejście nigdy nie będzie większe niż liczba miejsc po przecinku po punkcie na pierwszym wejściu?Odpowiedzi:
APL (Dyalog) , 4 bajty
Dyalog APL wykorzystuje wystarczającą precyzję wewnętrzną.
Wypróbuj online!
⍎⍞
wykonać ciąg znaków⎕⍕
uzyskaj dane numeryczne i użyj tego jako precyzji formatowaniaźródło
Perl,
2220 bajtówZa pomocą:
Jest to wersja kodu Dady. Poprzedni:
źródło
printf"%.*f",pop,pop
powinien działaćPHP,
3331 bajtówPHP też zaokrągla poprawnie (przynajmniej w wersji 64-bitowej):
pobiera dane wejściowe z argumentów wiersza poleceń. Uruchom z
-r
.PHP, brak wbudowanych, 133 bajtów
Uruchom go
-nr
lub przetestuj online .awaria
Bajt zerowy nie działa; więc muszę użyć
substr
.źródło
"%.$argv[2]f"
zamiast"%.{$argv[2]}f"
, oszczędzając 2 bajty.Ruby 2.3, 12 + 45 = 57
Korzysta z
BigDecimal
wbudowanego, ale musi być wymagany przed użyciem, co jest tańsze jako flaga.Flaga:
-rbigdecimal
funkcja:
Domyślnie używa Ruby 2.3
ROUND_HALF_UP
źródło
JavaScript (ES6), 44 bajty
Wypróbuj online:
źródło
Python,
114105103969189 bajtówZaoszczędź 5 bajtów dzięki Kevinowi Cruijssenowi
Zaoszczędź 2 bajty dzięki Krazorowi
Wypróbuj online!
źródło
from decimal import *
a usunięcie tych trzechd.
jest o 4 bajty krótsze.d=Decimal
ad()
co uratowałoby kolejne 5. (Może być źle, bardzo sennie)REXX, 24 bajty
Ponieważ REXX zawsze używa tekstowej reprezentacji liczb, prawidłowe zaokrąglanie liczb jest bezpłatne.
Wypróbuj online!
źródło
BASH,
262321 bajtówstosowanie
zapisz w round_string.sh, chmod + x round_string.sh
edycja: nie trzeba ładować biblioteki
źródło
14.22
to dane wejściowe14.225 2
, a nie14.23
AHK, 25 bajtów
Znowu jestem przytłoczony niemożnością użycia przez AHK parametrów przekazanych bezpośrednio w funkcjach, które akceptują nazwę zmiennej lub liczbę. Jeśli mogę wymienić
a
z1
wRound
funkcji, używa wartości1
. Gdy próbuję%1%
, próbuje użyć pierwszego argumentu za treść jako nazwy zmiennej, która nie działa. Konieczność ustawienia go jako innej zmiennej najpierw kosztowała mnie 6 bajtów.źródło
Partia, 390 bajtów
Wyjaśnienie. Zaczyna od wyodrębnienia znaku, jeśli dotyczy. Następnie dzieli liczbę na liczby całkowite i ułamkowe. Ułamek jest wypełniany
n+1
zerami, aby mieć więcej niżn
cyfry.n
P (zero indeksowane) cyfrowy dzieli się przez 5, a to początkowa przenoszenia.n
Cyfry całkowite i ułamkowe są łączone, a przeniesienie dodawane znak po znaku. (Dodatkowe zera chronią przed falowaniem przenoszenia). Po zatrzymaniu falowania przenoszenia liczba jest rekonstruowana i wstawiany jest przecinek dziesiętny.źródło
TI-Basic,
5316 bajtówTI-Basic nie używa IEEE, a poniższa metoda działa dla 0-9 (włącznie) pozycji dziesiętnych.
Dzięki @JulianLachniet za wykazanie, że cielęta CE mają
toString(
polecenie, którego nie znałem (wymagana jest edycja Calcs OS 5.2 lub nowsza).PS Miałem drugą linię,
sub(Str1,1,N+inString(Str1,".
ale potem zdałem sobie sprawę, że to było bezużyteczne.źródło
N
stosować?Java 7,
777271 bajtów-1 bajt dzięki @cliffroot
72-bajtowa odpowiedź:
W przeciwieństwie do Pythona, Java już zaokrągla poprawnie i już zwraca ciąg, gdy używasz
String.format("%.2f", aDouble)
z2
zastąpioną liczbą miejsc po przecinku, którą chcesz.EDYCJA / UWAGA: Tak, wiem, że
new Float(n)
jest o 1 bajt krótszy niżnew Double(n)
, ale najwyraźniej nie udaje się to z przypadkami testowymi123456789.987654321
. Zobacz ten kod testowy dotyczący Double vs Float.Wyjaśnienie:
Kod testowy:
Wypróbuj tutaj.
Wynik:
źródło
<T>T c(T n,int d){return(T)"".format("%."+d+"f",new Double(n+""));}
123456789.987654321, 4
powinno być123456789.9877
, nie123456789.9876
Python (2/3), 394 bajty
Działa dla dowolnych liczb dokładności.
źródło
s[0]<'0'
i może również wykorzystywać ciąg mnożeniam='-'*(s[0]<'0')
. Linie bez przedziałów instrukcji blokowych można łączyć z;
(npo='';c=0
.). Niektóreif
instrukcje można prawdopodobnie zastąpić indeksowaniem list, aby jeszcze bardziej ograniczyć potrzebę podziału wiersza i tabulacji. W ostatnim wierszu można użyć plasterkao[::-1]
zamiastreversed(o)
i''.join
jest nadmiarowy. Możesz również być w stanie przepisać go, aby uniknąć konieczności używania wielureturn
instrukcji.JavaScript (ES6), 155 bajtów
Objaśnienie: Łańcuch jest najpierw znormalizowane do przechowywania
.
in+1
dziesiętnych cyfr. Końcowa cyfra, wszelkie poprzedzające9
s lub.
s oraz dowolna poprzedzająca cyfra są następnie brane pod uwagę. Jeśli ostatnia cyfra jest mniejsza niż 5, wówczas i wszystkie bezpośrednio poprzedzające.
są po prostu usuwane, ale jeśli jest większa niż 5,9
s są zmieniane na0
s, a poprzednia cyfra jest zwiększana (lub 1 prefiks, jeśli nie było poprzedniej cyfry).źródło
Python 3 + SymPy, 54 bajty
Wypróbuj online!
źródło
Scala, 44 bajty
Test:
źródło
Cud , 10 bajtów
Stosowanie:
Ustaw dokładność dziesiętną i w razie potrzeby dodaj końcowe zera.
źródło
npm i -g wonderlang
. Użyjwonder
polecenia, aby odpalić REPL i wkleić kod.J,
2217 bajtówDzięki @Conor O'Brien za poprawienie mojego zrozumienia zasad.
źródło
2 t '1234.456'
powinien dać1234.46
zamiast6 t '1234.456'