Como arredondar cgfloat
-
28-09-2019 - |
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?
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
erounded
continuam a serCGFloat
. Se você precisar de umInt
você tem que convertê -lo comoInt(myCGFloat)
. - Não há necessidade de usar as funções de matemática C
round(x)
,ceil(x)
efloor(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 comroundf
,ceilf
efloorf
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 é