O módulo de matemática do Python contém funções úteis como floor
& ceil
. Essas funções usam um número de ponto flutuante e retornam o número inteiro mais próximo abaixo ou acima dele. No entanto, essas funções retornam a resposta como um número de ponto flutuante. Por exemplo:
import math
f=math.floor(2.3)
Agora f
retorna:
2.0
Qual é a maneira mais segura de obter um número inteiro desse float, sem correr o risco de erros de arredondamento (por exemplo, se o float é o equivalente a 1.99999) ou talvez eu deva usar outra função completamente?
python
math
integer
python-2.x
Boaz
fonte
fonte
math.floor
retorna um ponto flutuante na v2.6 , mas retorna um número inteiro na v3 . Neste ponto (quase seis anos após o PO), esse problema pode aparecer raramente.Respostas:
Todos os números inteiros que podem ser representados por números de ponto flutuante têm uma representação exata. Então você pode usar com segurança
int
no resultado. Representações inexatas ocorrem apenas se você estiver tentando representar um número racional com um denominador que não é um poder de dois.Que isso funcione não é nada trivial! É uma propriedade da representação de ponto flutuante IEEE que int∘floor = ⌊⋅⌋ se a magnitude dos números em questão for pequena o suficiente, mas diferentes representações são possíveis onde int (floor (2.3)) pode ser 1.
Para citar a Wikipedia ,
fonte
O uso
int(your non integer number)
vai pregar.fonte
floor
rodadas para baixo enquantoint
rodadas para a 0.int(-2.3)
na distribuição Python Canopy 2.7.6 e obtive-2
como esperado. Os números inteiros podem ser negativos, da mesma forma na definição formal de matemática.int(-2.3)
dá-2
como você diz, porque se aproxima0
, ou seja , neste caso. Por outro lado, a pergunta original usadamath.floor
, que sempre arredonda para baixo:math.floor(-2.3)
dá-3.0
.math.floor
, e esta resposta mostra como converter um número flutuante em um número inteiro. Tome a bóia demath.floor
e canalizá-lo atravésint
, problema resolvido:int(math.floor(2.3))
Você poderia usar a função round. Se você não usar um segundo parâmetro (número de dígitos significativos), acho que obterá o comportamento desejado.
Saída IDLE.
fonte
round
retorna um número flutuante também, pelo menos no Python 2.6.round
efloor
retornam números inteiros no Python 3.x. Então, suponho que a pergunta se refira ao Python 2.x.int(round(2.65))
?round(6.5)
dá 6? Parece meio queceil()
flutuar quando há um 5 imediato (ou superior a 9) após o decimal em todos os outros casos. Por que isso não está funcionando neste caso? ou qualquer outro caso, quando as extremidades número com um seis e há a 5 logo após o decimal ...Combinando dois dos resultados anteriores, temos:
Isso converte um número flutuante em um número inteiro de maneira bastante confiável.
fonte
float
representando um número maior do que o normalint
pode conter. No Python 2, existemfloat
valores que você só pode representar usando along
(após o arredondamento)?int()
função produz tanto umint
oulong
com base no que é necessário ...Este post explica por que funciona nesse intervalo .
Em um dobro, você pode representar números inteiros de 32 bits sem problemas. Não pode haver problemas de arredondamento. Mais precisamente, as dobras podem representar todos os números inteiros entre 2 53 e -2 53 inclusive .
Breve explicação : Um duplo pode armazenar até 53 dígitos binários. Quando você precisar de mais, o número é preenchido com zeros à direita.
Daqui resulta que 53 ones é o maior número que pode ser armazenado sem preenchimento. Naturalmente, todos os números (inteiros) que exigem menos dígitos podem ser armazenados com precisão.
Adicionar um a 111 (omitido) 111 (53 unidades) produz 100 ... 000 (53 zeros). Como sabemos, podemos armazenar 53 dígitos, o que resulta no preenchimento zero mais à direita.
É daí que vem o 2 53 .
Mais detalhes: Precisamos considerar como o ponto flutuante IEEE-754 funciona.
O número é calculado da seguinte maneira (excluindo casos especiais que são irrelevantes aqui):
onde viés = 2 expoente - 1 - 1 , ou seja, 1023 e 127 para precisão dupla / única, respectivamente.
Sabendo que multiplicar por 2 X simplesmente muda todos os bits X para a esquerda, é fácil ver que qualquer número inteiro deve ter todos os bits na mantissa que terminam à direita do ponto decimal em zero.
Qualquer número inteiro, exceto zero, tem o seguinte formato em binário:
Como excluímos zero, sempre haverá um MSB, e é por isso que não é armazenado. Para armazenar o número inteiro, devemos trazê-lo para a forma acima mencionada: -1 sinal × 1.mantissa × 2 expoente - viés .
É o mesmo que mudar os bits sobre o ponto decimal até que haja apenas o MSB à esquerda do MSB. Todos os bits à direita do ponto decimal são armazenados na mantissa.
A partir disso, podemos ver que podemos armazenar no máximo 52 dígitos binários além do MSB.
Segue-se que o número mais alto em que todos os bits são armazenados explicitamente é
Para isso, precisamos definir o expoente, de modo que o ponto decimal seja deslocado em 52 casas. Se aumentarmos o expoente em um, não saberemos o dígito da direita para a esquerda após o ponto decimal.
Por convenção, é 0. Definindo a mantissa inteira como zero, recebemos o seguinte número:
Isso é 1 seguido de 53 zeros, 52 armazenados e 1 adicionado devido ao expoente.
Representa 2 53 , que marca o limite (negativo e positivo) entre o qual podemos representar com precisão todos os números inteiros. Se quiséssemos adicionar um a 2 53 , teríamos que definir o zero implícito (indicado por
x
) para um, mas isso é impossível.fonte
math.floor
sempre retornará um número inteiro e, portantoint(math.floor(some_float))
, nunca introduzirá erros de arredondamento.O erro de arredondamento já pode ter sido introduzido
math.floor(some_large_float)
, ou mesmo ao armazenar um grande número em um float em primeiro lugar. (Números grandes podem perder precisão quando armazenados em carros alegóricos.)fonte
int
efloor
retorne valores diferentes para números negativos, é claro.Se você precisar converter uma seqüência de caracteres flutuante em um int, poderá usar esse método.
Exemplo:
'38.0'
para38
Para converter isso em um int, você pode convertê-lo como um float e depois em um int. Isso também funcionará para cadeias flutuantes ou cadeias inteiras.
Nota : Isso retira qualquer número após o decimal.
fonte
Outro exemplo de código para converter um real / flutuante em um número inteiro usando variáveis. "vel" é um número real / flutuante e convertido para o próximo mais alto INTEGER, "newvel".
fonte
Como você está pedindo a maneira 'mais segura', fornecerei outra resposta que não seja a principal.
Uma maneira fácil de garantir que você não perca nenhuma precisão é verificar se os valores serão iguais após a conversão.
Se o float for 1,0, por exemplo, 1,0 é igual a 1. Portanto, a conversão para int será executada. E se o float for 1.1, int (1.1) equivale a 1 e 1.1! = 1. Portanto, o valor permanecerá um float e você não perderá nenhuma precisão.
fonte
df ['Nome_da_coluna'] = df ['Nome_da_coluna']. astype (int)
fonte