Round to n Sig Figs

20

Défi

Étant donné un nombre xet un nombre n, arrondissez le nombre xà ndes chiffres significatifs et sortez le résultat.

Chiffres significatifs

Les chiffres significatifs d'un nombre sont des chiffres qui portent un sens contribuant à sa résolution de mesure. Cela inclut tous les nombres sauf les zéros non significatifs.

Gardez à l'esprit que les zéros non significatifs après un point décimal sont toujours des chiffres insignifiants .

Lorsque vous arrondissez un chiffre, vous devez arrondir à zéro si le chiffre suivant est supérieur ou égal à cinq.

Tous les zéros à la fin après un point décimal sont comptés comme significatifs.

Contribution

Le premier nombre sera x, le nombre à arrondir. Le deuxième chiffre sera nle nombre de chiffres significatifs que vous devez arrondir x.

xsera un nombre (votre code doit gérer à la fois des entiers et des virgules flottantes) compris entre -1 000 000 000 et 1 000 000 000 inclus. nsera un entier positif compris entre 1 et 50 inclus. nne sera jamais supérieur au nombre de chiffres x.

L'entrée ne sera jamais 0ou sous aucune forme 0, par exemple 0.000ou 000.

Exemples

Inputs: 2.6754, 2
Output: 2.7

Une sortie de 2.7000ne serait pas valide car les zéros de fin après le point décimal sont comptés comme des chiffres significatifs.


Inputs: 0.00034551, 4
Output: 0.0003455

Inputs: 50237.1238, 3
Output: 50200

Notez que cela ne doit pas avoir de point décimal.


Inputs: 2374905, 1
Output: 2000000

Inputs: 543.0489, 4
Output: 543.0

Inputs: 15, 1
Output: 20

Inputs: 520.3, 3
Output: 520

Si vous le souhaitez, vous pouvez produire à la 520.place mais pas 520.0.


Inputs: -53.87, 2
Output: -54

Inputs: 0.0999, 2
Output: 0.10

Règles

Les fonctions et bibliothèques intégrées qui vous permettent d'arrondir un nombre à ndes chiffres significatifs sont interdites.

Gagnant

Le code le plus court en octets gagne.

Beta Decay
la source
4
Car Inputs: 520.3, 3le point décimal de la réponse n'est-il pas 520.crucial?
Greg Martin
5
@GregMartin Je crois que oui, car c'est la seule chose qui lui donne 3 figues sig vs 2
Suever
3
@BetaDecay Non, ce n'est pas le cas. Le point décimal serait nécessaire pour cela.
mbomb007
3
"200 est considéré comme n'ayant qu'un seul chiffre significatif" - chemistry.bd.psu.edu/jircitano/sigfigs.html
mbomb007
4
@DLosc C'est pourquoi, si c'était le résultat, vous 2.0 x 10^2l'écririez réellement en affichant les 2 sigfigs.
mbomb007

Réponses:

3

Python 3, 83 octets

(similaire à la réponse PHP)

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

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

Production:

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

En plus d'être légèrement plus longue, une autre approche que j'ai envisagée:

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

... produit une sortie incorrecte pour l'entrée de (15, 1):

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

... en raison de l'imprécision en virgule flottante dans la round()fonction. Il me semble probable que je pourrais trouver des cas de test qui briseraient la méthode "arrondir à zéro décimale" également si je regardais assez fort.

Ainsi, il me semble que ma solution n'est probablement pas 100% correcte pour tous les cas et ne le serait que si elle était calculée en décimal. Ce problème peut donc affecter les solutions dans n'importe quel langage utilisant l'arithmétique FP.

Simon
la source
Enregistrez quelques octets en mettant le corps de ssur la même ligne, puis en utilisant des points-virgules. def s(x,n):y=10**(ceil(log10(abs(x)))-n);return y*round(x/y)
Cyoce
En outre, vous pouvez supprimer l'espace import *pour le rendreimport*
Cyoce
votre réponse pour moi n'est pas correcte car les règles disent: "Les fonctions intégrées et les bibliothèques qui vous permettent d'arrondir un nombre à n chiffres significatifs sont interdites." Et vous utilisez la fonction ronde avec n = 0
RosLuP
@RosLuP: La round()fonction arrondit à la ndécimale, pas aux nchiffres significatifs, donc elle a été autorisée pour cet événement de golf.
Simon
5

PHP, 130 octets

<?=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 octets fonctionne avec des valeurs <1 pour les chiffres significatifs

<?=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 octets fonctionne mais ignore les zéros inutiles

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

Quelqu'un a volé ou supprimé la fonction round en PHP! Pour rendre le défi plus intéressant. 127 octets

<?=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
la source
Il saute également les zéros indécents. C'est une version où j'utilise pas la fonction native round en PHP uniquement pour plaisanter. Il appartient à la version 56 octets que je préfère
Jörg Hülsermann
Ok sinon utilisez le tour de la bibliothèque ....
RosLuP
3

Lot, 660 652 octets

@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

Explication: commence par le suffixe a .du paramètre au cas où il n'en aurait pas déjà un, puis supprime le signe (qui est enregistré) et les zéros non significatifs. La variable résultante mest enregistrée pour plus tard car elle nous indiquera la magnitude souhaitée du résultat. Tous les .s sont ensuite supprimés, ce qui pourrait entraîner d'autres zéros non significatifs, ils sont donc également supprimés. nles zéros sont suffixés pour garantir qu'il y a suffisamment de chiffres à arrondir, puis les ne et premier nchiffres sont extraits. Si le ne chiffre n'est pas 4 ou moins, alors nous ajoutons fastidieusement 1à la chaîne. Si la chaîne déborde, nous augmentons l'amplitude en préfixant a 1, mais si elle était à l'origine inférieure à 0.1ce que nous faisons, en supprimant le 1nous venons d'ajouter et également un0après la virgule décimale. Si la magnitude est encore inférieure à celle-ci, 1nous copions les zéros après la virgule décimale dans le résultat, mais si c'est le cas, 1nous extrayons la partie entière de la réponse, en ajoutant des zéros supplémentaires si nécessaire pour atteindre la virgule décimale (qui est alors supprimé car il afficherait une précision incorrecte). Enfin, le signe, la partie entière, le point décimal et la partie décimale sont concaténés.

Neil
la source