Como posso converter um dobro no valor inteiro mais próximo?

147

Como você converte um duplo no int mais próximo?

leora
fonte

Respostas:

78

Use Math.round(), possivelmente em conjunto comMidpointRounding.AwayFromZero

por exemplo:

Math.Round(1.2) ==> 1
Math.Round(1.5) ==> 2
Math.Round(2.5) ==> 2
Math.Round(2.5, MidpointRounding.AwayFromZero) ==> 3
nickf
fonte
6
Não Convert.ToInt32()fará a mesma coisa ou simplesmente tira tudo após o decimal?
The Muffin Man
208
Na verdade, não produz um número inteiro, mas um duplo.
31512 Gatoneich
13
@ Ronnie - não, isso é por design. Por padrão, Math.Round arredondará os números do ponto médio (x + 0,5) para o número par mais próximo . Se você deseja um comportamento diferente, é necessário especificá-lo através de um sinalizador. msdn.microsoft.com/en-us/library/system.midpointrounding.aspx
nickf
6
Bem eu nunca! :)
Ronnie
5
Double não é Int.
Evgeni Nabokov
267
double d = 1.234;
int i = Convert.ToInt32(d);

Referência

Manipula o arredondamento da seguinte forma:

arredondado para o número inteiro assinado de 32 bits mais próximo. Se o valor estiver na metade do caminho entre dois números inteiros, o número par será retornado; ou seja, 4,5 é convertido em 4 e 5,5 é convertido em 6.

John Sheehan
fonte
7
Muito melhor do que Math.Roundquando ele retorna um int conforme necessário.
Keith
10
@ robert-koritnik. Não sei por que isso é "inválido". O OP não especificou uma regra de arredondamento preferida e "arredondar 0,5 para o par mais próximo" é a regra padrão desde o início. Sempre arredondar para cima tem efeitos estatísticos indesejados.
Keith
@ Keith: Eu não sei, mas sempre fui ensinado a arredondar x.5 para cima, mas posso ver o raciocínio para fazer isso para cima ou para baixo para estatísticas. Obrigado por isso. PS É claro que não estou nas estatísticas, finanças ou contabilidade, onde esse tipo de arredondamento parece ser o padrão .
Robert Koritnik
3
"Sempre arredondar para cima tem efeitos estatísticos indesejados" - isso é simplesmente falso. O arredondamento de 0,5 para cima arredonda exatamente metade dos números - [0,.5)- para baixo e exatamente metade dos números - [.5,1)- para cima. Arredondamento para até um pouco influencia até mesmo números, uma vez que arredonda (.5,1.5)a 1, mas [1.5,2.5]a 2.
Jim Balter
11
@JimBalter Como o zero não é arredondado, o arredondamento para metade apresenta um viés positivo, portanto, é conhecido como arredondamento assimétrico. A "metade da rodada para o par" não acontece, se a sua distribuição for uniforme o suficiente e o arredondamento não influenciar números pares ou desiguais. Veja o desempate no meio do caminho .
Sdds 24/09
36

Você também pode usar a função:

//Works with negative numbers now
static int MyRound(double d) {
  if (d < 0) {
    return (int)(d - 0.5);
  }
  return (int)(d + 0.5);
}

Dependendo da arquitetura, é várias vezes mais rápido.

szymcio
fonte
Isso foi perfeito para mim, pois o Math.Round não estava funcionando do jeito que eu queria.
317 Hanna
@cullub sim, sim. Ele converte o d duplo que tinha 0,5 anexado a ele em um número inteiro.
Darrell
Este é o meu método preferido - funciona de uma maneira muito simples. Muito mais curto e fácil de ler que Math.Round (d, MidpointRounding.AwayFromZero) e mais conciso do que usar uma instrução if para escolher se deve arredondar para baixo ou para cima. E, na verdade, retorna um inteiro, no final, não uma dupla
binderbound
3
Veja o comentário do @ Eternal21 abaixo para comportamento estranho em números negativos (MyRound (-1.2) = 0)
Chris
2
Para quem se pergunta, o problema mencionado por @Chris agora é supostamente resolvido verificando se o valor é negativo.
John Weisz
14
double d;
int rounded = (int)Math.Round(d);

fonte
5

Sei que essa pergunta é antiga, mas me deparei com ela na busca pela resposta para minha pergunta semelhante. Eu pensei em compartilhar a dica muito útil que me foi dada.

Ao converter para int, basta adicionar .5seu valor antes da redução. Como o downcasting intsempre cai para o número mais baixo (por exemplo (int)1.7 == 1), se seu número for .5maior ou igual, a adição .5trará para o próximo número e seu downcast intdeve retornar o valor correto. (por exemplo (int)(1.8 + .5) == 2)

Trent
fonte
13
O problema é se você tentar converter valores negativos dessa maneira. Por exemplo, -1,25 terminará igual a 0. (-1,25 + 0,5 = 0,75 e, uma vez convertido para int, será 0). Então você precisa subtrair 0,5 dos valores negativos.
Eternal21
Pode-se usar+ 0.5 * Math.Abs(d)
TaW
-1

Para o Unity, use Mathf.RoundToInt .

using UnityEngine;

public class ExampleScript : MonoBehaviour
{
    void Start()
    {
        // Prints 10
        Debug.Log(Mathf.RoundToInt(10.0f));
        // Prints 10
        Debug.Log(Mathf.RoundToInt(10.2f));
        // Prints 11
        Debug.Log(Mathf.RoundToInt(10.7f));
        // Prints 10
        Debug.Log(Mathf.RoundToInt(10.5f));
        // Prints 12
        Debug.Log(Mathf.RoundToInt(11.5f));

        // Prints -10
        Debug.Log(Mathf.RoundToInt(-10.0f));
        // Prints -10
        Debug.Log(Mathf.RoundToInt(-10.2f));
        // Prints -11
        Debug.Log(Mathf.RoundToInt(-10.7f));
        // Prints -10
        Debug.Log(Mathf.RoundToInt(-10.5f));
        // Prints -12
        Debug.Log(Mathf.RoundToInt(-11.5f));
    }
}

Fonte

public static int RoundToInt(float f) { return (int)Math.Round(f); }
zwcloud
fonte
Q não menciona nem etiqueta o Unity.
XenoRo 30/07/19
@XenoRo Eu estava respondendo a essa pergunta antiga para quem procura respostas semelhantes ao usar o Unity.
Zwcloud 31/07/19
2
Você pode responder suas próprias perguntas para compartilhar conhecimento. Crie uma pergunta separada específica para a API (neste caso, Unity) em casos como este. As respostas devem ser apropriadas às perguntas. Caso contrário, poderia haver uma resposta aqui para cada API C # única com uma função de arredondamento.
XenoRo 02/08/19
-2

Estou desenvolvendo uma calculadora científica que ostenta um botão Int. Eu descobri o seguinte é uma solução simples e confiável:

double dblInteger;
if( dblNumber < 0 )
   dblInteger = Math.Ceiling(dblNumber);
else
   dblInteger = Math.Floor(dblNumber);

Às vezes, Math.Round produz resultados inesperados ou indesejáveis ​​e a conversão explícita em número inteiro (via conversão ou Convert.ToInt ...) geralmente produz valores incorretos para números de maior precisão. O método acima parece sempre funcionar.

Mark Jones
fonte
2
isso não arredonda todos os negativos e fecha todos os números positivos? Esse não é necessariamente o número inteiro "mais nítido".
Tim Pohlmann
este não é o número mais próximo.
Samer Aamar 17/05
1
Dado 1,99, isso retorna 1,0.
Jon Schneider