Pergunta

eu quero o resultado de uma equação arredondado para o número inteiro mais próximo. por exemplo.

137 * (3/4) = 103

Considere o seguinte código incorreto.

int width1 = 4;
int height1 = 3;

int width2 = 137;
int height2 = width2 * (height1 / width1);

O que é a maneira correta de executar "inteiro" matemática em C #?

Eu realmente tenho que fazer:

int height2 = (int)Math.Round(
      (float)width2 * ((float)height1 / (float)width1)
   );
Foi útil?

Solução

Como dito acima, você deve fazer a multiplicação antes da divisão. De qualquer forma, você pode escrever a sua expressão com lançando apenas o divisor:

int height2 = (int)Math.Round(width2 * (height1 / (float)width1));

Outras dicas

int height2 = (width2 * height1) / width1;

Do multiplicação primeiro (contanto que não é provável que overflow) e segunda divisão.

3/4 == 0 em matemática inteiro (matemática inteiro não-redonda sobre a divisão, ele trunca).

arredondamento Se você realmente precisa, você tem que quer trabalhar em ponto fixo, ponto flutuante, ou brincar com o módulo.

Eu acho que esta é a maneira mais elegante de fazer isso:

Math.round(myinteger * 0.75);

Usando 0,75 em vez de 3/4 irá lançá-lo implicitamente a um / float casal e por que não usar as funções padrão que são fornecidos para isso?

Vou fixar o código incorreto, adicionando zero linhas de código:

float width1 = 4;
float height1 = 3;

float width2 = 137;
float height2 = width2 * (height1 / width1);

Você deve usar carros alegóricos para as variáveis ??que podem eventualmente conter decimais. Isto inclui alturas calculadas a partir das proporções. Você sempre pode lançar para int mais tarde, se isso é um problema.

Nunca lançado para flutuar, tem ainda menos precisão do que um inteiro de 32-bit. Se você estiver indo para usar ponto flutuante, use sempre casal em vez de float.

Apenas tropeçou esta questão. A resposta de Aaron parece quase certo para mim. Mas estou muito certo de que você precisa para especificar midpointrounding se o seu problema é um problema "mundo real". Assim, a minha resposta, com base no código de Arão, é

int height2 = (int)Math.Round(width2 * (height1 / (float)width1),MidpointRounding.AwayFromZero);

Para ver a diferença de execução que código na consola

    Console.WriteLine((int)Math.Round(0.5));
    Console.WriteLine((int)Math.Round(1.5));
    Console.WriteLine((int)Math.Round(2.5));
    Console.WriteLine((int)Math.Round(3.5));
    Console.WriteLine((int)Math.Round(0.5, MidpointRounding.AwayFromZero));
    Console.WriteLine((int)Math.Round(1.5, MidpointRounding.AwayFromZero));
    Console.WriteLine((int)Math.Round(2.5, MidpointRounding.AwayFromZero));
    Console.WriteLine((int)Math.Round(3.5, MidpointRounding.AwayFromZero));
    Console.ReadLine();

Para mais detalhes você pode olhar este artigo .

Seis anos (arredondada) mais tarde, aqui está a minha contribuição -. Um pequeno truque que aprendi há muito tempo, e estou surpreso que ninguém tenha mencionado aqui

A idéia é fazer arredondamentos, adicionando metade do divisor para o numerador antes de fazer a divisão.

    int height2 = (width2 * height1 + width1 / 2) / width1;

Na realidade eu não necessariamente recomendo fazer isso em casos, como o OP de, onde o divisor é uma variável. Em vez disso, pode ser melhor usar Math.Round (), como é muito mais fácil de entender.

Mas nos casos em que o divisor é uma constante que faço usar esse truque. Assim em vez de

    int height2 = width2 * height1 / 4;  // No rounding

Eu usaria

    int height2 = (width2 * height1 + 2) / 4;

Aqui está um exemplo mais típico

  private static Size ResizeWithPercentage(Size oldSize, int resizePercentage)
  {
     return new Size((oldSize.Width * resizePercentage + 50) / 100, 
                     (oldSize.Height * resizePercentage + 50) / 100);
  }

Outra possibilidade é combinar este truque com a ideia mencionada por dongilmore e supercat que em vez de ter uma divisão por dois especificado ou implícito, você pode multiplicar o numerador eo denominador por dois.

    int height2 = (width2 * height1 * 2 + width1) / (width1 * 2);

Isto dá melhores respostas nos casos em que o divisor é, ou pode ser, um número ímpar.

A elaborada na mensagem de Jeffery, desde que você geralmente uma melhor chance de decimais necessários truncadas do que você tem de transbordar um inteiro de 32-bit (e porque a multiplicação e divisão é comutativa), geralmente você deve fazer a multiplicação antes da divisão.

conversões converso sempre ronda, por isso:

int height2 = Convert.ToInt32(width2 * height1 / (double)width1);
int height2 = ((width2 * height1 * 10) + 5) / (width1 * 10);

Antes de qualquer divisão inteira, certifique-se de que o divisor não é zero. Além disso, note isso pressupõe quociente positivo. Se negativo, necessidades de arredondamento para ser -5, não +5.

Uma abordagem razoavelmente eficaz se a divisão final será por um número par eo resultado será sempre positivo é dividir pela metade desse valor, adicione um, e dividir por dois. Se o resultado pode ser negativo, você deve, se possível adicionar uma quantidade que vai fazer tudo ser positivo, fazer o cálculo, e em seguida, subtrair uma quantidade correspondente depois.

Se a divisão final será por um número ímpar, multiplique o numerador e denominador por 2, em seguida, proceda como acima. Por exemplo, para calcular um * 5/7, arredondada, (a*10+1)>>1 computação. A única coisa a observar é que você pode precisar para estender seus valores para um tipo numérico maior para estouro evitar ou, se isso não for possível, subdividir a divisão em pedaços. Por exemplo, para calcular uma * 14/15, você pode calcular ((a * 4/3 * 7) / 5 + 1) / 2. Que a computação pode ainda estouro se um é muito grande, mas a faixa permitida será três vezes tão grande como se ele foi avaliada sem fazer a dividir por 3 antes da outra divisão. Note-se que subdividir a operação fará com que o ligeiramente arredondamento menos precisa, mas ainda perto o suficiente para muitos propósitos.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top