Arredondar um número de ponto flutuante até o número inteiro mais próximo?


127

Como o título sugere, quero pegar um número de ponto flutuante e arredondá-lo para o número inteiro mais próximo. No entanto, se não for um todo, SEMPRE quero arredondar a variável, independentemente de quão próxima ela esteja do próximo número inteiro acima. Existe uma maneira de fazer isso?


2
Uma possível dificuldade é que os formatos de ponto flutuante IEEE podem representar números tão grandes que a grandularidade é maior que 1. Portanto, enquanto você pode arredondar x para baixo, arredondar x + 1 para baixo não fornecerá o resultado esperado.
dmckee --- gatinho ex-moderador

Por favor, publique alguns exemplos.
Ashwini Chaudhary

Respostas:


178

Simples

print int(x)

irá funcionar também.


7
int (0,6) = 0 em vez de 1
Helin Wang

39
@HelinWang Isso é exatamente o que o OP pediu.
precisa

5
Esta parece ser a abordagem mais pitônica.
Gyan Veda

23
Isso funciona bem para números positivos, mas os números negativos serão arredondados:int(-23.3) == 23
Alex Riley

2
e não funciona para números além do intervalo inteiro, como 600851475143, basicamente sinaliza um erro de memória.
Muyide Ibukun

77

Um destes deve funcionar:

import math
math.trunc(1.5)
> 1
math.trunc(-1.5)
> -1
math.floor(1.5)
> 1
math.floor(-1.5)
> -2

14
A saída de math.truncé um número inteiro, enquanto a saída de math.flooré um número flutuante.
Evedovelli 29/11

6
@evedovelli: Na verdade, não mais. type(math.floor(1.51)) -> inte a type(math.trunc(1.51)) -> intpartir depython 3.6.0
SKPS

4
Essas opções são mais explícitas que "int (x)" e, portanto, são mais pitônicas.
Tristan

43
x//1

O //operador retorna o piso da divisão. Como dividir por 1 não altera seu número, isso é equivalente ao piso, mas não é necessária nenhuma importação. Notas:

  1. Isso retorna um flutuador
  2. Isso gira em direção a -∞

Adição agradável. int(-1.1) == -1embora, -1.1//1 == -2.0no entanto decimal.Decimal('-1.1')//1 == decimal.Decimal('-1')(conforme documentado, a reivindicação 2 não seja verdadeira decimal), confiar em como o //comportamento não é totalmente estável, ainda hoje.
Tino

28

Para obter resultado de ponto flutuante, basta usar:

round(x-0.5)

Também funciona para números negativos.


6
extremamente sofisticado que é
Alon


9

muitas pessoas dizem usar int(x), e isso funciona bem na maioria dos casos, mas há um pequeno problema. Se o resultado do OP for:

x = 1.9999999999999999

vai arredondar para

x = 2

após o dia 16 de setembro, ele será arredondado. Isso não é grande coisa, se você tiver certeza de que nunca encontrará algo assim. Mas é algo a ter em mente.


17
Isso ocorre porque 1.9999999999999999na verdade é igual a 2.0na representação float64 interna. I. e. ele já é arredondado assim que é analisado em um flutuador, pois um flutuador de 64 bits não pode representar tantos dígitos significativos. Você pode verificar isso com a avaliação 1.9999999999999999 == 2.0. E se você suspeitar que a operação igual faz algum arredondamento em flutuadores, você pode comparar a representação binária com struct.pack("d", 1.9999999999999999) == struct.pack("d", 2.0), que também é igual.
precisa saber é o seguinte

4
E se esse é exatamente o seu ponto, então não vejo o que há de errado int(). O valor já é de 2,0 e vai convertê-lo em felizmente 2.
blubberdiblub

1
Se a intenção do OP (ou de quem o ler no futuro) for usar o número inteiro mais próximo (e não o valor de arredondamento) por qualquer motivo, será algo a ter em mente.
Lokilindo 13/08/16

3
@lokilindo Mas isso não tem nada a ver int(), apenas tem a ver com o uso inadequado defloat , como 1.9999999999999999é arredondado para o 2.0 tempo de compilação (enquanto int()é chamado no tempo de execução). Se você usar o tipo de dados correto para a variável, tudo funciona como esperado: int(decimal.Decimal('1.9999999999999999999999999999999999999999999999999999999'))1
Tino

6

Se você não deseja importar matemática, pode usar:

int(round(x))

Aqui está uma documentação:

>>> help(round)
Help on built-in function round in module __builtin__:

round(...)
    round(number[, ndigits]) -> floating point number

    Round a number to a given precision in decimal digits (default 0 digits).
    This always returns a floating point number.  Precision may be negative.

Obrigado pela sua resposta. Da próxima vez, você terá uma melhor recepção se escrever um código adequado (parênteses próximos) e fornecer alguma documentação.
Geoff

2
roundjá foi discutido e rejeitado como resposta quando essa pergunta foi feita há um ano. OP quer math.floor.
Adam Smith

3

Se você trabalha com numpy, pode usar a seguinte solução, que também funciona com números negativos (também funciona com matrizes)

import numpy as np
def round_down(num):
    if num < 0:
        return -np.ceil(abs(num))
    else:
        return np.int32(num)
round_down = np.vectorize(round_down)

round_down([-1.1, -1.5, -1.6, 0, 1.1, 1.5, 1.6])
> array([-2., -2., -2.,  0.,  1.,  1.,  1.])

Eu acho que também funcionará se você apenas usar o mathmódulo em vez do numpymódulo.


1

Não sei se você resolveu isso, mas eu apenas tropeço nessa questão. Se você quiser se livrar dos pontos decimais, use int (x) e ele eliminará todos os dígitos decimais. Não há necessidade de usar o círculo (x).


1

Apenas faça o arredondamento (x-0,5); isso sempre retornará o próximo valor inteiro arredondado para baixo do seu flutuador. Você também pode arredondar facilmente arredondando (x + 0,5)


-1

Pode ser muito simples, mas você não poderia arredondar para menos de 1? Por exemplo:

number=1.5
round(number)-1
> 1

4
Isso fornece a resposta errada para números inteiros inteiros. Por exemplo, 2,0 arredondado para cima é 2, e se você subtrair 1, obtém o resultado incorreto 1. #
Pascal Cuoq

@PascalCuoq Não entendi o seu problema. Você quer 1.0 como resultado? Porque o OP claramente queria arredondar e numerar para o mais próximo integer.
Bad_keypoints 14/05

1
@bad_keypoints Eu não acho que o OP quer rodada 2,0 para 1.
Pascal Cuoq

@PascalCuoq desculpe, eu apenas olhei para a resposta no tópico de comentários do qual somos.
Bad_keypoints 15/05

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.