Alguns números decimais não podem ser representados com precisão como flutuadores binários devido à representação interna dos flutuadores binários. Por exemplo: arredondar 14,225 para dois dígitos decimais não resulta em 14,23, como seria de esperar, mas em 14,22.
Python :
In: round(14.225, 2)
Out: 14.22
Suponha, no entanto, que tenhamos uma representação de string de 14,225 como '14 .225 ', devemos conseguir o arredondamento desejado '14 .23' como uma representação de string.
Essa abordagem pode ser generalizada com precisão arbitrária.
Possível solução 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
Uso :
# 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
Tarefa
Argumento de entrada 1 : uma string contendo
- pelo menos um dígito (
0
,1
,2
,3
,4
,5
,6
,7
,8
,9
), - no máximo um ponto decimal (
.
) que deve ser precedido por pelo menos um dígito, - um opcional menos (
-
) como primeiro caractere.
Argumento de entrada 2 : um número inteiro não negativo
Saída : a sequência corretamente arredondada (base 10)
arredondamento = Metade da rodada arredondada de zero
Este é um código de golfe . O menor número de bytes vence!
round(A,B
5 bytes0
não é um número inteiro positivo, é "não negativo".123.4 & 5 --> 123.40000
? Ou podemos assumir que a segunda entrada nunca será maior que a quantidade de casas decimais após o ponto na primeira entrada?Respostas:
APL (Dyalog) , 4 bytes
O Dyalog APL usa precisão interna suficiente.
Experimente online!
⍎⍞
executar entrada de string⎕⍕
obter entrada numérica e usar isso como precisão para formatarfonte
Perl,
2220 bytesUsando:
É a versão do código do Dada. Anterior:
fonte
printf"%.*f",pop,pop
deve trabalharPHP,
3331 bytesO PHP também arredonda corretamente (pelo menos em 64 bits):
recebe entrada dos argumentos da linha de comando. Corra com
-r
.PHP, sem built-ins, 133 bytes
Execute
-nr
ou teste on-line .demolir
Um byte nulo não funciona; então eu tenho que usar
substr
.fonte
"%.$argv[2]f"
vez de"%.{$argv[2]}f"
, economizando 2 bytes.Ruby 2.3, 12 + 45 = 57
Usa o
BigDecimal
built-in, mas precisa ser necessário antes do uso, o que é mais barato de fazer como um sinalizador.a bandeira:
-rbigdecimal
a função:
O Ruby 2.3 por padrão usa
ROUND_HALF_UP
fonte
Javascript (ES6), 44 bytes
Experimente online:
fonte
Python,
114105103969189 bytesGuardado 5 bytes graças a Kevin Cruijssen
Guardado 2 bytes graças a Krazor
Experimente online!
fonte
from decimal import *
e remover os trêsd.
é 4 bytes mais curto.d=Decimal
ed()
, o que economizaria outros 5. (Pode estar errado, com muito sono) #REXX, 24 bytes
Como o REXX sempre usa representação de texto dos números, o arredondamento correto dos números é gratuito.
Experimente online!
fonte
BASH,
262321 bytesuso
salve em round_string.sh, chmod + x round_string.sh
editar: não há necessidade de carregar a biblioteca
fonte
14.22
para a entrada14.225 2
, e não #14.23
AHK, 25 bytes
Mais uma vez, sou frustrado pela incapacidade do AHK de usar parâmetros passados diretamente em funções que aceitam um nome de variável ou um número. Se eu substituir
a
com1
naRound
função, ele usa o valor1
. Se eu tentar%1%
, ele tenta usar o conteúdo do primeiro argumento como um nome de variável, o que não funciona. Ter que defini-lo como outra variável primeiro me custou 6 bytes.fonte
Lote, 390 bytes
Explicação. Começa extraindo o sinal, se aplicável. Em seguida, divide o número em dígitos inteiros e de fração. A fração é preenchida com
n+1
zeros para garantir que tenha mais do quen
dígitos. On
th dígito (indexado a zero) é dividido por 5, e esse é o transporte inicial. Osn
dígitos do número inteiro e da fração são concatenados e o carry é adicionado caractere por caractere. (Os zeros extras se protegem contra a ondulação de transporte.) Após o transporte parar de ondular, o número é reconstruído e qualquer ponto decimal inserido.fonte
TI-Basic,
5316 bytesO TI-Basic não usa IEEE e o método abaixo funciona para 0-9 (inclusive) casas decimais.
Obrigado a @JulianLachniet por mostrar que os cálculos CE têm o
toString(
comando que eu não conhecia (são necessários o Color Edition calcs OS 5.2 ou superior).PS: Eu tinha uma segunda linha,
sub(Str1,1,N+inString(Str1,".
mas depois percebi que era inútil.fonte
N
usado?Java 7,
777271 bytes-1 byte graças a @cliffroot
Resposta de 72 bytes:
Ao contrário do Python, o Java já arredonda corretamente e já retorna uma String quando você usa
String.format("%.2f", aDouble)
o valor2
substituído com a quantidade de decimais desejada.EDIT / NOTE: Sim, eu sei que
new Float(n)
é 1 byte menor quenew Double(n)
, mas aparentemente falha nos casos de teste com123456789.987654321
. Veja este código de teste sobre Double vs Float.Explicação:
Código do teste:
Experimente aqui.
Resultado:
fonte
<T>T c(T n,int d){return(T)"".format("%."+d+"f",new Double(n+""));}
123456789.987654321, 4
deveria ser123456789.9877
, não123456789.9876
Python (2/3), 394 bytes
Trabalha para números de precisão arbitrários.
fonte
s[0]<'0'
e também pode usar a multiplicação de cadeiasm='-'*(s[0]<'0')
,. Linhas sem nenhum intervalo de declaração de bloco podem ser unidas com;
(por exemploo='';c=0
).if
Provavelmente, algumas instruções podem ser substituídas pela indexação de lista para reduzir ainda mais a necessidade de quebras de linha e guias. A linha final pode usar uma fatiao[::-1]
, em vez dereversed(o)
e''.join
é redundante. Você também pode reescrevê-lo para evitar a necessidade de váriasreturn
instruções.JavaScript (ES6), 155 bytes
Explicação: A sequência é normalizada primeiro para conter os dígitos a
.
en+1
decimal. O dígito à direita, qualquer9
s ou.
s anterior e qualquer dígito anterior, são considerados. Se o último dígito for menor que 5, ele e qualquer um imediatamente anterior.
serão simplesmente removidos, mas se for maior que 5, os9
s serão alterados para se0
o dígito anterior será incrementado (ou 1 prefixado se não houver dígito anterior).fonte
Python 3 + SymPy, 54 bytes
Experimente online!
fonte
Scala, 44 bytes
Teste:
fonte
Maravilha , 10 bytes
Uso:
Defina a precisão decimal e adicione zeros à direita, se necessário.
fonte
npm i -g wonderlang
. Use owonder
comando para o fogo até a REPL e colar o código no.J,
2217 bytesAgradeço a @Conor O'Brien por corrigir minha compreensão das regras.
fonte
2 t '1234.456'
deve dar em1234.46
vez de6 t '1234.456'