Arrotondare a Sig Fig


20

Sfida

Dato un numero xe un numero n, arrotondare il numero xa ncifre significative e produrre il risultato.

Figure significative

Le cifre significative di un numero sono cifre che portano significato contribuendo alla sua risoluzione di misura. Ciò include tutti i numeri tranne gli zeri iniziali.

Ricorda che gli zero iniziali dopo un punto decimale sono ancora cifre insignificanti .

Quando si arrotonda una cifra, è necessario arrotondare da zero se la cifra seguente è maggiore o uguale a cinque.

Tutti gli zero finali dopo un punto decimale vengono considerati significativi.

Ingresso

Il primo numero sarà x, il numero da arrotondare. Il secondo numero sarà nil numero di cifre significative a cui dovresti arrotondare x.

xsarà un numero (il tuo codice dovrebbe gestire sia numeri interi che punti mobili) tra -1.000.000.000 e 1.000, 000.000 inclusi. nsarà un numero intero positivo compreso tra 1 e 50 inclusi. nnon sarà mai maggiore del numero di cifre in x.

L'input non sarà mai 0o qualsiasi forma di 0, ad esempio 0.000o 000.

Esempi

Inputs: 2.6754, 2
Output: 2.7

Un output di non 2.7000sarebbe valido perché gli zero finali dopo il punto decimale sono contati come cifre significative.


Inputs: 0.00034551, 4
Output: 0.0003455

Inputs: 50237.1238, 3
Output: 50200

Si noti che questo non deve avere un punto decimale.


Inputs: 2374905, 1
Output: 2000000

Inputs: 543.0489, 4
Output: 543.0

Inputs: 15, 1
Output: 20

Inputs: 520.3, 3
Output: 520

Se lo desideri, puoi 520.invece produrre ma non 520.0.


Inputs: -53.87, 2
Output: -54

Inputs: 0.0999, 2
Output: 0.10

Regole

Le funzioni e le librerie integrate che consentono di arrotondare un numero a ncifre significative non sono consentite.

vincente

Vince il codice più breve in byte.


4
Perché Inputs: 520.3, 3, il punto decimale nella risposta non è 520.cruciale?
Greg Martin,

5
@GregMartin Credo di si, visto che è l'unica cosa che lo fa avere 3 fichi di sig vs. 2
Suever

3
@BetaDecay No non lo è. Il punto decimale sarebbe richiesto per quello.
mbomb007,

3
"200 è considerato avere una sola cifra significativa" - chemistry.bd.psu.edu/jircitano/sigfigs.html
mbomb007

4
@DLosc Ecco perché se fosse il risultato, lo scriverei come 2.0 x 10^2, mostrando i 2 sigfigs.
mbomb007,

Risposte:


3

Python 3, 83 byte

(simile alla risposta PHP)

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

Casi test:

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

Produzione:

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

Oltre ad essere leggermente più lungo, un altro approccio che ho considerato:

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

... produce un output errato per l'ingresso di (15, 1):

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

... a causa di imprecisione in virgola mobile nella round()funzione. Mi sembra probabile che potrei trovare casi di test che spezzerebbero il metodo "arrotondare a zero cifre decimali" anche se avessi guardato abbastanza.

Quindi, mi sembra che la mia soluzione probabilmente non sia corretta al 100% per tutti i casi e non lo sarebbe se non fosse calcolata in decimale. Questo problema può quindi influire sulle soluzioni in qualsiasi linguaggio che utilizza l'aritmetica FP.


Salvare alcuni byte inserendo il corpo della sstessa riga, quindi usando i punti e virgola. def s(x,n):y=10**(ceil(log10(abs(x)))-n);return y*round(x/y)
Cyoce,

Inoltre, puoi rimuovere lo spazio import *per farloimport*
Cyoce

la tua risposta per me non è giusta perché le regole dicono: "Le funzioni e le librerie integrate che ti consentono di arrotondare un numero a n cifre significative non sono consentite". E usi la funzione rotonda con n = 0
RosLuP il

@RosLuP: la round()funzione arrotonda a ncifre decimali, non a ncifre significative, quindi è stato consentito per questo evento di golf.
Simon,

5

PHP, 130 byte

<?=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 byte funziona con valori <1 per le cifre significative

<?=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 byte funziona ma salta zero inutili

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

Qualcuno ha rubato o cancellato la funzione rotonda in PHP! Per rendere la sfida più interessante. 127 byte

<?=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);

Salta anche gli zeri inconsueti. È una versione in cui non uso la funzione round nativa in PHP solo per scherzo. Appartiene alla versione a 56 byte che preferirei
Jörg Hülsermann,

Ok se non usare la libreria rotonda ....
RosLuP il

3

Lotto, 660 652 byte

@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

Spiegazione: Inizia aggiungendo il suffisso .a al parametro nel caso in cui non ne abbia già uno, quindi taglia il segno (che viene salvato) e tutti gli zeri iniziali. La variabile risultante mviene salvata per dopo perché ci dirà l'entità desiderata del risultato. Eventuali .s vengono quindi rimossi, il che potrebbe comportare ulteriori zeri iniziali, quindi vengono rimossi anche. nvengono aggiunti degli zeri per garantire che ci siano abbastanza cifre da arrotondare, quindi vengono estratte la nprima e la prima ncifra. Se la nterza cifra non è 4 o inferiore, aggiungeremo noiosamente 1alla stringa. Se la stringa trabocca, aumentiamo la grandezza con il prefisso a 1, ma se era originariamente inferiore a quello 0.1che facciamo rimuovendo il valore 1appena aggiunto e anche un0dopo il punto decimale. Se la grandezza è ancora inferiore a 1allora copiamo gli zeri dopo il punto decimale sul risultato, tuttavia se lo è 1o più, estraiamo la parte intera della risposta, aggiungendo ulteriori zeri se necessario per raggiungere il punto decimale (che è quindi cancellato perché mostrerebbe una precisione errata). Infine, vengono concatenati il ​​segno, la parte intera, il punto decimale e la parte decimale.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.