Pergunta

Eu fiz este método

+ (CGFloat) round: (CGFloat)f {
    int a = f;
    CGFloat b = a;
    return b;
}

Funciona como esperado, mas apenas completa. E se for um número negativo, ele ainda redondo.

Esse foi apenas um método rápido que fiz, não é muito importante que ele arredonda corretamente, eu apenas cheguei aos valores X e Y da câmera para o meu jogo.

Este método está bem? É rápido? ou há uma solução melhor?

Foi útil?

Solução

Já existem funções padrão com comportamentos que você pode precisar em <math.h> tal como: floorf, ceilf, roundf, rintf e nearbyintf (LASF 'f' significa versão "float", versões sem ela são versões "duplas").

É melhor usar métodos padrão não apenas porque são padrão, mas porque funcionam melhor em casos de borda.

Atualização de 2013 (JEDEdC)

O iOS não tem mais apenas 32 bits. Existem várias outras respostas para esta pergunta que agora são mais relevantes.

A maioria das respostas menciona importação tgmath.h

Outras dicas

Resposta de 2018

As outras respostas aqui são datadas ou não dão bons exemplos. É fácil arredondar um CGFloat Usando o Swift embutido rounded função.

let x: CGFloat = 3.5
let y = x.rounded() // 4.0

Se você quiser arredondar o valor em lugar, pode usar round:

var x: CGFloat = 3.5
x.round() // 4.0

Regras de arredondamento

Se você deseja um controle mais preciso sobre como os números são arredondados, você pode usar um FloatingPointRoundingRule.

Longe de zero

x.rounded(.awayFromZero)

Os números acima de zero são arredondados e os números abaixo de zero são arredondados.

3.000  ->  3.0
3.001  ->  4.0
3.499  ->  4.0
3.500  ->  4.0
3.999  ->  4.0

-3.000  ->  -3.0
-3.001  ->  -4.0
-3.499  ->  -4.0
-3.500  ->  -4.0
-3.999  ->  -4.0

Baixa

x.rounded(.down)

Receita qualquer número com um valor decimal até o próximo número inteiro menor. Isso é o mesmo que floor(x).

3.000  ->  3.0
3.001  ->  3.0
3.499  ->  3.0
3.500  ->  3.0
3.999  ->  3.0

-3.000  ->  -3.0
-3.001  ->  -4.0
-3.499  ->  -4.0
-3.500  ->  -4.0
-3.999  ->  -4.0

Para mais próximo ou longe de zero

x.rounded(.toNearestOrAwayFromZero)   // same as x.rounded()

Os números decimais são arredondados para o valor inteiro mais próximo. No entanto, quando o valor é exatamente no meio (como 3.5 ou -3.5) Em seguida, os números positivos são arredondados e os números negativos são arredondados.

Pode ter um nome longo complicado, mas é normalmente assim que se aprende arredondando na escola. É também a regra usada se você apenas faz x.rounded().

3.000  ->  3.0
3.001  ->  3.0
3.499  ->  3.0
3.500  ->  4.0  ***
3.999  ->  4.0

-3.000  ->  -3.0
-3.001  ->  -3.0
-3.499  ->  -3.0
-3.500  ->  -4.0  ***
-3.999  ->  -4.0

Para mais próximo ou mesmo

x.rounded(.toNearestOrEven)

Isso é semelhante a toNearestOrAwayFromZero, exceto agora o .5 Os valores são arredondados para o número inteiro uniforme.

3.000  ->  3.0
3.001  ->  3.0
3.499  ->  3.0
3.500  ->  4.0   ***
3.999  ->  4.0
4.500  ->  4.0   ***

-3.000  ->  -3.0
-3.001  ->  -3.0
-3.499  ->  -3.0
-3.500  ->  -4.0   ***
-3.999  ->  -4.0
-4.500  ->  -4.0   ***

Em direção a zero

x.rounded(.towardZero)

Isso apenas tem o efeito de cortar quaisquer valores decimais. Se você precisava de um Int você poderia fazer a mesma coisa com Int(x).

3.000  ->  3.0
3.001  ->  3.0
3.499  ->  3.0
3.500  ->  3.0
3.999  ->  3.0

-3.000  ->  -3.0
-3.001  ->  -3.0
-3.499  ->  -3.0
-3.500  ->  -3.0
-3.999  ->  -3.0

Acima

x.rounded(.up)

Este é o oposto de .down. Todos os números decimais são arredondados. Isso é o mesmo que ceil(x).

3.000  ->  3.0
3.001  ->  4.0
3.499  ->  4.0
3.500  ->  4.0
3.999  ->  4.0

-3.000  ->  -3.0
-3.001  ->  -3.0
-3.499  ->  -3.0
-3.500  ->  -3.0
-3.999  ->  -3.0

Notas

  • Não se esqueça de levar em consideração os valores negativos.
  • Os resultados de round e rounded continuam a ser CGFloat. Se você precisar de um Int você tem que convertê -lo como Int(myCGFloat).
  • Não há necessidade de usar as funções de matemática C round(x), ceil(x) e floor(x) não mais. No entanto, se você os usar, eles lidam com a arquitetura de 64 e 32 bits, para que todas as respostas que você possa ter visto com roundf, ceilf e floorf agora são obsoletos.

UMA CGFloat é tipedef'd para um double ou a float, para que você possa contorná -los como qualquer outro tipo real:

CGFloat round(CGFloat aFloat)
{
    return (int)(aFloat + 0.5);
}

Observe que, embora isso funcione com flutuadores pequenos o suficiente para carregar uma fração, ele pode agir estranho em grandes valores.

Tentar #import "tgmath.h".

o <tgmath.h> O cabeçalho incluirá os cabeçalhos <math.h> e <complex.h> e definirá várias macros genéricas do tipo.

Você está reinventando a roda - e essa é uma pergunta c, não objetiva C. Apenas use a função padrão C Round ().

Para trabalhar com 32 e 64 bits, você pode criar suas próprias macro

#ifndef CGFLOAT_CEIL
    #ifdef CGFLOAT_IS_DOUBLE
        #define CGFLOAT_CEIL(value) ceil(value)
    #else
        #define CGFLOAT_CEIL(value) ceilf(value)
    #endif
#endif

PS Isso não é uma resposta para a pergunta, mas uma adição para a pergunta sobre como trabalhar com valores de 32/64 bits.

Defina isso em um arquivo como mymacros.h e adicione uma importação no myappprefix.pch

Lembre -se também de que escolher o cgfloat como prefixo para sua função pode ser um risco, pois a Apple pode adicionar uma macro como essa, e é por isso que o #ifndef cgfloat_ceil é

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