Como eu conseguiria executar math.ceil
tal número que é atribuído à próxima potência mais alta de 10?
# 0.04 -> 0.1
# 0.7 -> 1
# 1.1 -> 10
# 90 -> 100
# ...
Minha solução atual é um dicionário que verifica o intervalo do número de entrada, mas é codificado permanentemente e eu prefiro uma solução de uma linha. Talvez esteja faltando um truque matemático simples ou uma função numpy correspondente aqui?
10
cima para baixo, isso precisará de algo com, por exemplolog10
.Respostas:
Você pode usar
math.ceil
commath.log10
para fazer isso:log10(n)
fornece a soluçãox
que satisfaz10 ** x == n
; portanto, se você arredondar,x
ele fornece o expoente para a próxima potência mais alta de 10.Observe que, para um valor em
n
quex
já seja um número inteiro, a "próxima potência mais alta de 10" serán
:fonte
10 ** math.ceil(math.log10(1)) == 1
, que não é "a próxima potência mais alta"Seu problema está subespecificado, você precisa voltar atrás e fazer algumas perguntas.
Em outra resposta, foi proposto pegar o logaritmo, arredondar para cima (função de teto) e depois exponenciar.
Infelizmente, isso sofre erros de arredondamento. Antes de tudo, n é convertido de qualquer tipo de dado que possua em um número de ponto flutuante de precisão dupla, potencialmente introduzindo erros de arredondamento, e o logaritmo é calculado, potencialmente introduzindo mais erros de arredondamento, tanto em seus cálculos internos quanto em seu resultado.
Como tal, não demorei muito para encontrar um exemplo em que desse um resultado incorreto.
Também é teoricamente possível que fracasse na outra direção, embora isso pareça ser muito mais difícil de provocar.
Portanto, para uma solução robusta para flutuadores e entradas, precisamos assumir que o valor do nosso logaritmo é apenas aproximado e, portanto, devemos testar algumas possibilidades. Algo ao longo das linhas de
Acredito que este código deve fornecer resultados corretos para todos os argumentos em uma gama sensata de magnitudes no mundo real. Ele será interrompido por números muito pequenos ou muito grandes de tipos de pontos não inteiros e não flutuantes devido a problemas ao convertê-los em ponto flutuante. Casos especiais do Python argumentam argumentos inteiros para a função log10 na tentativa de impedir o estouro, mas ainda com um número inteiro suficientemente grande, pode ser possível forçar resultados incorretos devido a erros de arredondamento.
Para testar as duas implementações, usei o seguinte programa de teste.
Isso encontra muitas falhas na implementação ingênua, mas nenhuma na implementação aprimorada.
fonte
round
vez demath.ceil
? Isso apresentará muitos casos desnecessários onder < n
é verdade e, portanto, ele precisa executar um trabalho adicional.Parece que você quer a menor potência seguinte de 10 ... Aqui está uma maneira de usar matemática pura e sem log, mas com recursão.
fonte
Algo assim talvez? Está no topo da minha cabeça, mas funcionou quando tentei alguns números no terminal.
fonte
Veja isso!
Este código é baseado no princípio do poder de dez
len( str( int( float_number ) ) )
.Existem 4 casos:
int( i ) > 1
.Float
number - convertido paraint
, a partir daí, a stringstr()
, nos dará umstring
com olength
qual estamos olhando exatamente. Então, primeira parte, para entradai > 1.0
- são dez10
neste poder.i > 1.0
ei > 0.1
<=> é10
e1
respectivamente.i < 0.1
: Aqui, dez estarão em poder negativo. Para obter o primeiro elemento diferente de zero após a vírgula, usei essa construção("%.100f" % i ).replace('.','').index( k )
, em que k é executado no[1:10]
intervalo. Depois disso, faça o mínimo da lista de resultados. E diminuir por um, é o primeiro zero, que será contado. Além disso, aqui padrão python doindex()
pode falhar, se não vai encontrar pelo menos um de diferente de zero elemento de[1:10]
intervalo, é por isso que, no final, eu devo "filtro" listando por ocorrência:if str( j ) in "%.100f" % i
. Além disso, para ficar mais preciso -%.100f
pode ser diferente.fonte