ios - ¿Cómo ceder o cementar con seguridad un CGFloat a int?
math floating-point (3)
EDITAR - lee los comentarios por las razones por las cuales esta respuesta no es correcta :)
Lanzar un float
a un int
es un floorf
implícito ie (int)5.9
es 5
. Si no te importa, entonces simplemente echa :)
Si desea redondear, simplemente lanzar el resultado de un ceilf
- casting después del redondeo no debe introducir ningún error (o, si lo desea, agregar uno antes del lanzamiento, es decir, `(int) (5.9 + 1) ''es'' 6 ''- lo mismo que redondear).
Para redondear al más cercano, simplemente agregue 0.5 - (int)(5.9+0.5)
es 6
pero (int)(5.4+0.5)
es 5
. Aunque solo usaría roundf(5.9)
:)
A menudo necesito CGFloat
o CGFloat
un CGFloat
a un int
, para el cálculo de un índice de matriz.
El problema que veo permanentemente con floorf(theCGFloat)
o ceilf(theCGFloat)
es que puede haber problemas con las imprecisiones de punto flotante.
Entonces, ¿qué CGFloat
si mi CGFloat
es 2.0f
pero internamente se representa como 1.999999999999f
o algo así? Hago floorf
y obtengo 1.0f
, que es un flotador de nuevo. Y, sin embargo, debo lanzar esta bestia a int, que puede presentar otro problema.
¿Existe una mejor práctica de cómo plantar o cementar un float
en un int
tal manera que algo como 2.0
nunca se derribara accidentalmente a 1
y algo como 2.0
nunca llegaría accidentalmente a 2
?
Hay un par de conceptos erróneos en su pregunta.
¿Qué pasa si mi CGFloat es 2.0f pero internamente está representado como 1.999999999999f
no puede suceder; 2.0, como todos los enteros razonablemente pequeños, tiene una representación exacta en coma flotante. Si tu CGFloat
es 2.0f
, entonces realmente es 2.0.
algo como 2.0 nunca accidentalmente llegaría al límite de 2
El techo de 2.0 es 2; ¿Qué más podría ser?
Creo que la pregunta que realmente está haciendo es "supongamos que hago un cálculo que produce un resultado inexacto, que matemáticamente debería ser exactamente 2.0, pero en realidad es un poco menos; cuando aplico floor
a ese valor, obtengo 1.0 en lugar de 2.0 ¿Cómo puedo prevenir esto?
Esa es en realidad una pregunta bastante sutil que no tiene una sola respuesta "correcta". ¿Cómo has calculado el valor de entrada? ¿Qué vas a hacer con el resultado?
Respuesta suplementaria Swift
Estoy agregando esto como una respuesta complementaria para aquellos que vienen aquí buscando cómo usar floor
y ceil
con un CGFloat
(como yo lo hice).
var myCGFloat: CGFloat = 3.001
floor(myCGFloat) // 3.0
ceil(myCGFloat) // 4.0
Y si se necesita un Int
, entonces se puede convertir a uno.
var myCGFloat: CGFloat = 3.001
Int(floor(myCGFloat)) // 3
Int(ceil(myCGFloat)) // 4
Actualizar
Ya no es necesario usar las funciones C floor
y ceil
. Puede usar la round()
Swift round()
con reglas de redondeo .
var myCGFloat: CGFloat = 3.001
myCGFloat.round(.down) // 3.0
myCGFloat.round(.up) // 4.0
Si no desea modificar las variables originales, utilice rounded()
.
Notas
- Funciona con arquitecturas de 32 y 64 bits.
Ver también
- Cómo redondear CGFloat