Zaokrąglij do n Sig Fig

20

Wyzwanie

Biorąc pod uwagę liczbę xi liczbę n, zaokrąglaj liczbę xdo nliczb znaczących i generuj wynik.

Znaczące liczby

Znaczącymi liczbami liczby są cyfry, które niosą znaczenie, przyczyniając się do jej rozdzielczości pomiaru. Dotyczy to wszystkich liczb oprócz zer wiodących.

Pamiętaj, że wiodące zera po przecinku są nadal nieistotnymi cyframi.

Zaokrąglając cyfrę, należy zaokrąglić od zera, jeśli następna cyfra jest większa lub równa pięć.

Wszystkie zera końcowe po przecinku są liczone jako znaczące.

Wejście

Pierwszą liczbą będzie xliczba do zaokrąglenia. Druga liczba to nliczba znaczących liczb, które należy zaokrąglić x.

xbędzie liczbą (twój kod powinien obsługiwać zarówno liczby całkowite, jak i zmiennoprzecinkowe) od -1 000 000 000 do 1 000 000 000 włącznie. nbędzie dodatnią liczbą całkowitą od 1 do 50 włącznie. nnigdy nie będzie większy niż liczba cyfr w x.

Wkładem nigdy nie będzie 0ani żadna forma 0, np . 0.000Lub 000.

Przykłady

Inputs: 2.6754, 2
Output: 2.7

Wyjście 2.7000byłoby niepoprawne, ponieważ końcowe zera po przecinku są liczone jako liczby znaczące.


Inputs: 0.00034551, 4
Output: 0.0003455

Inputs: 50237.1238, 3
Output: 50200

Pamiętaj, że nie może to być kropka dziesiętna.


Inputs: 2374905, 1
Output: 2000000

Inputs: 543.0489, 4
Output: 543.0

Inputs: 15, 1
Output: 20

Inputs: 520.3, 3
Output: 520

Jeśli chcesz, możesz 520.zamiast tego wyświetlać dane wyjściowe 520.0.


Inputs: -53.87, 2
Output: -54

Inputs: 0.0999, 2
Output: 0.10

Zasady

Wbudowane funkcje i biblioteki, które pozwalają zaokrąglić liczbę do nznaczących liczb, są niedozwolone.

Zwycięski

Najkrótszy kod w bajtach wygrywa.

Rozpad beta
źródło
4
Bo Inputs: 520.3, 3czy przecinek dziesiętny w odpowiedzi nie jest 520.istotny?
Greg Martin
5
@GregMartin Wierzę, że tak, ponieważ jest to jedyna rzecz, która sprawia, że ​​ma 3 figi kontra 2
Suever
3
@BetaDecay Nie, to nie jest. Wymagany byłby do tego przecinek dziesiętny.
mbomb007
3
„Uważa się, że 200 ma tylko JEDNĄ znaczącą liczbę” - chemistry.bd.psu.edu/jircitano/sigfigs.html
mbomb007 16.09.16
4
@DLosc Właśnie dlatego, jeśli byłby to wynik, napisalibyśmy go jako 2.0 x 10^2, pokazując 2 sigfigs.
mbomb007

Odpowiedzi:

3

Python 3, 83 bajty

(podobny do odpowiedzi PHP)

from math import *
def s(x,n):
 y=10**(ceil(log10(abs(x)))-n)
 return y*round(x/y)

Przypadki testowe:

tests = [(2.6754,2), (0.00034551, 4), (50237.1238, 3),
        (2374905, 1), (543.0489, 4), (15, 1), (520.3, 3), (-53.87, 2)]

print ([s(x,n) for x,n in tests])

Wynik:

[2.7, 0.0003455, 50200, 2000000, 543.0, 20, 520, -54]

Poza tym, że jestem nieco dłuższy, inne podejście, które rozważałem:

from math import *
def s(x,n):
 z=ceil(log10(abs(x)))
 return "%.*f"%(n-z,10**z*round(x/10**z,n))

... produkuje niepoprawne wyjście dla wejścia (15, 1):

['2.7', '0.0003455', '50200', '2000000', '543.0', '10', '520', '-54']

... z powodu niedokładności zmiennoprzecinkowej w round()funkcji. Wydaje mi się prawdopodobne, że mógłbym znaleźć przypadki testowe, które przełamałyby metodę „zaokrąglania do zera po przecinku”, także gdybym wystarczająco się starał.

Tak więc wydaje mi się, że moje rozwiązanie prawdopodobnie nie jest w 100% poprawne dla wszystkich przypadków i nie byłoby, chyba że zostało obliczone w systemie dziesiętnym. Ten problem może zatem wpływać na rozwiązania w dowolnym języku wykorzystującym arytmetykę FP.

Szymon
źródło
Zapisz niektóre bajty, umieszczając treść sw tym samym wierszu, a następnie używając średników. def s(x,n):y=10**(ceil(log10(abs(x)))-n);return y*round(x/y)
Cyoce,
Możesz także usunąć miejsce, import *aby to zrobićimport*
Cyoce,
twoja odpowiedź nie jest dla mnie w porządku, ponieważ zasady mówią: „Wbudowane funkcje i biblioteki, które pozwalają zaokrąglić liczbę do n znaczących liczb, są niedozwolone”. I używasz funkcji okrągłej z n = 0
RosLuP
@RosLuP: round()Funkcja zaokrągla do nmiejsc po przecinku, a nie do nliczb znaczących, więc było dozwolone dla tego wydarzenia golfowego.
Simon
5

PHP, 130 bajtów

<?=number_format($r=round($i=$argv[1],($n=$argv[2])-ceil(log(abs($i),10))),($d=(1+floor(log(abs($r),10))-$n))<0?abs($d):0,".","");

PHP, 133 bajtów działa z wartościami <1 dla liczb znaczących

<?=number_format($r=round($i=$argv[1],($n=$argv[2])-floor(log(abs($i),10))-1),($d=(1+floor(log(abs($r),10))-$n))<0?abs($d):0,".","");

PHP, 56 bajtów działa, ale pomija niepotrzebne zerowanie

<?=round($i=$argv[1],$argv[2]-floor(log(abs($i),10))-1);

Ktoś ukradł lub usunął funkcję rundy w PHP! Aby wyzwanie było bardziej interesujące. 127 bajtów

<?=ceil($x=($i=$argv[1])*10**(($r=$argv[2])-($l=floor(log(abs($i),10))+1)))-$x<=0.5?ceil($x)*10**($l-$r):floor($x)*10**($l-$r);
Jörg Hülsermann
źródło
Pomija także nieczyste Zera. Jest to wersja, w której nie używam natywnej funkcji okrągłej w PHP tylko do żartów. Należy do 56
bajtowej
Ok, jeśli nie, użyj rundy biblioteki ....
RosLuP,
3

Partia, 660 652 bajtów

@echo off
set m=%1.
set s=
if %m:~,1%==- set s=-&set m=%m:~1%
:m
if %m:~,1%==0 set m=%m:~1%&goto m
set d=%m:.=%
:d
if %d:~,1%==0 set d=%d:~1%&goto d
for /l %%i in (1,1,%2) do call set d=%%d%%0
call set r=%%d:~%2,1%%
call set d=%%d:~,%2%%
if %r% leq 4 goto r
set r=
:i
set/ai=1+%d:~-1%
set r=%i:~-1%%r%
set d=%d:~,-1%
if %i% leq 9 set d=%d%%r%&goto r
if not "%d%"=="" goto i
set d=1%r:~1%
set m=1%m%
set m=%m:1.0=.%
:r
if %m:~,2%==.0 set m=%m:.0=.%&set d=0%d%&goto r
set i=0
set p=.
:l
if %m:~,1%==. echo %s%%i%%p%%d%&exit/b
if %i%==0 set i=
if "%d%"=="" set d=0&set p=
set i=%i%%d:~,1%
set d=%d:~1%
set m=%m:~1%
goto l

Objaśnienie: Zaczyna się od sufiksu a .parametru w przypadku, gdy jeszcze go nie ma, a następnie przycina znak (który jest zapisany) i wszelkie zera wiodące. Wynikowa zmienna mjest zapisywana na później, ponieważ powie nam pożądaną wielkość wyniku. Wszelkie .s są następnie usuwane, co może skutkować dalszymi zerami wiodącymi, więc są one również usuwane. nzera są sufiksowane, aby zapewnić wystarczającą liczbę cyfr do zaokrąglenia, a następnie wyodrębniane są cyfry nth i pierwsze ncyfry. Jeśli nta cyfra nie jest równa 4 lub mniej, nużąco dodajemy 1do łańcucha. Jeśli łańcuch się przepełnia, wówczas zwiększamy wielkość przez prefiks a 1, ale jeśli pierwotnie był mniejszy 0.1, robimy to przez usunięcie 1właśnie dodanego i a0po przecinku. Jeśli jasność jest wciąż mniejsza niż 1wtedy, kopiujemy zera po przecinku do wyniku, jednak jeśli jest 1lub więcej, to wyodrębniamy część całkowitą odpowiedzi, dodając dodatkowe zera, jeśli to konieczne, aby osiągnąć przecinek dziesiętny (który jest wtedy usunięty, ponieważ pokazywałby nieprawidłową precyzję). Wreszcie znak, część całkowita, przecinek dziesiętny i część dziesiętna są łączone.

Neil
źródło