Arredondamento satisfatório
Você sabe quando está na aula de ciências e pediu para arredondar para 2 sig figs, mas a sua resposta é 5.2501...
? Você deve arredondar para 5.3
, mas isso é tão insatisfatório! Ao arredondar para 5.3
, você sai com 0,05, o que é uma grande quantia em comparação com 0,1 (o valor do local para o qual você está arredondando)! Então me ajude de uma maneira satisfatória.
Para arredondar de maneira satisfatória, você deve arredondar no primeiro dígito que encontrar, que produz um erro relativamente pequeno - menos da metade do erro máximo possível ao arredondar. Basicamente, você precisa arredondar sempre que encontrar 0, 1, 8 ou 9. Se isso nunca acontecer, retorne a entrada como está. Não use zeros à esquerda ou zeros - isso simplesmente não parece satisfatório.
Entrada
Um valor de sequência ou flutuante que representa um número decimal não negativo.
Resultado
O mesmo número decimal arredondado satisfatoriamente, no formato string ou float.
Exemplos
Input -> Output
0 -> 0
0.5 -> 0.5
0.19 -> 0
0.8 -> 1
5.64511 -> 5.645
18.913 -> 20
88.913 -> 100
36.38299 -> 36.4
621 -> 620
803.22 -> 1000
547.4726 -> 547.4726
Este é um desafio do código-golfe , pelo que o código mais curto vence!
fonte
036.40000
consideradas uma saída válida?.0
parte será dada para números inteiros? Além disso,0
não é positivo.19
volta para,20
mas0.19
volta para0
? Por quê?Respostas:
JavaScript (ES6),
100 99 9878 bytesRecebe a entrada como uma sequência. Retorna um flutuador.
Experimente online!
Quão?
Primeiro, adicionamos um0 0 à sequência de entrada, para garantir um dígito antes de um possível 8 ou 9 , que deve acionar o arredondamento imediatamente.
O sinalizadorj é definido como 1 , desde que procuremos um dígito no qual possamos fazer um arredondamento satisfatório e definido como 0 0 depois.
Como um0 0 foi adicionado à string pela qual estamos caminhando, mas s foi deixado inalterado, d contém o caractere atual s [ i ] está apontando para o próximo caractere.
Usamos o código a seguir para carregar o próximo dígito emn , ignorando um possível separador decimal:
Embora as strings sejam imutáveis no JavaScript, a expressãos [ i ] + 1 se contiver um valor numérico, mesmo que s [ i ] não seja realmente incrementado. Portanto, a expressão fa l s e (forçado a 0 0 ) para todos os dígitos (incluindo 0 0 ) e a t r u e (forçado a 1 ) para o separador decimal
++s[i]
retornará!++s[i]
é avaliada para"."
.Quando o arredondamento ocorre, produzimosn for 0 0 ou 1 (e não for o dígito inicial da entrada original) e n 8 9 j 0 0 0 0 d 1
d + --j
se o próximo dígitod + j--
sefonte
Ruby ,
7977696765 bytesExperimente online!
Explicação
->n
Receber entrada como uma stringz=n+".0"
Crie uma sequência temporáriaz
que garanta que contenha um ponto e um dígito relevante.i=z=~/\./
Determine a posição do ponto decimalz
e atribua ai
.z[i]=''
Solte o ponto para que ele não atrapalhe ainda mais.z=~/(?!^)[01]|8|9/
Determine a posição de não partida0-1
ou qualquer8-9
, o que ocorrer primeiro.(...)-i
Essa diferença será o número de casas decimais a manter, negativo se arredondarmos para a esquerda do ponto.n.to_f.round ...
Converta para flutuar e faça o arredondamento.fonte
Geléia , 34 bytes
Experimente online!
-1 graças a Jonathan Allan .
fonte
ŒV
? Eu acho queV
vai funcionar também._>¥0ɓVær
como o meu é (eu perdi o uso da rápida dyadic por isso obrigado também!)Geléia ,
3029 bytes-1 graças a Erik, o Outgolfer (uso rápido diádico
¥
de sua resposta)Um link monádico que aceita uma lista de caracteres que produz um float.
Experimente online! Ou veja a suíte de testes .
Quão
Primeiro, observe que a sequência de entrada é composta exclusivamente dos caracteres
0123456789.
que têm ordinais[48,49,50,51,52,53,54,55,56,57,46]
, que têm restos quando divididos por oito[0,1,2,3,4,5,6,7,0,1,6]
. Os únicos personagens que são entre-1
e1
inclusiva são0
,1
,8
, e9
.Além disso, se subtrairmos oito dos ordinais (
[40,41,42,43,44,45,46,47,48,49,38]
), o mesmo (obviamente) é válido. Se dividirmos pela metade esses ([20,20.5,21,21.5,22,22.5,23,23.5,24,24.5,19]
), os únicos caracteres que têm remanescentes quando divididos por oito que estão entre-1
e1
inclusive são8
e9
.fonte
Retina 0.8.2 , 75 bytes
Experimente online! O link inclui casos de teste. Explicação:
Lidar com o caso de um líder
8
ou9
.Se houver um não-líder
0
ou1
, zere-o e o restante da string. Além disso, se houver um8
ou9
, deixe-o, mas zere o restante da string. (Mas mantenha o ponto decimal inalterado em ambos os casos.)Se ainda houver um
8
ou9
a nesse ponto, zere-o e aumente o dígito anterior (possivelmente antes do ponto decimal).Exclua zeros à direita se estiverem após um ponto decimal, mas exclua apenas o ponto decimal se não houver outros dígitos no meio.
fonte
C (gcc) ,
111102 bytesExperimente online!
fonte
C # (compilador interativo do Visual C #) , 280 bytes
Experimente online!
Pode ser mais curto se eu usei duplas em vez de decimais, mas usei decimais para preservar a precisão; caso contrário, um número como 547.4726 seria 547.472595214844.
C # (compilador interativo do Visual C #) , 268 bytes
Experimente online! (Versão menos precisa)
fonte