16

배열 색인을 계산할 때 종종 CGFloat에서 int까지 바닥이나 천장이 필요합니다.int에 CGFloat를 안전하게 바닥 또는 천장에 고정시키는 방법은 무엇입니까?

floorf(theCGFloat) 또는 ceilf(theCGFloat)으로 영구적으로 표시되는 문제는 부동 소수점 부정확성에 문제가있을 수 있다는 것입니다.

CGFloat2.0f이지만 내부적으로는 1.999999999999f 또는 그와 비슷한 것으로 표시됩니다. 나는 floorf을하고 1.0f을 얻습니다. 이것은 다시 float입니다. 그런데 또 다른 문제를 야기 할 수있는이 짐승을 int로 던져야합니다.

가장 좋은 방법은 어떻게 바닥이나 천장을 만들다가있는 floatint2.0 같은 실수 실수 2에 천정이 붙은 만나지 것 2.0 같은 1 무언가에 낭패하지 얻을 않을 것 같은 것을?

+4

이 정답 일 수 없습니다보기 높거나 낮다. 이전 반올림 오류로 인해 값이 너무 높아지고 값이 너무 낮아서 값이 인위적으로 조정되어 선행 오류를 보완하기 때문에 너무 높은 값을 반홖하는 것과 반대로 반홖하는 트레이드 오프가 있습니다. 문맥에 대한 설명이 없으면 단 하나의 정답이 없다. –

답변

19

질문에 몇 가지 오해가 있습니다. 내 CGFloat는 2.0f하지만 내부적으로는 1.999999999999f로 표현되는 경우

이 일어날 수없는 것을

; 2.0은 합리적으로 작은 정수와 마찬가지로 부동 소수점으로 정확하게 표현됩니다. CGFloat2.0f 인 경우 실제로는 2.0입니다.

무언가 같이 2.0 실수로 2

에 천정이 붙은 만나지 것

2.0 의 천장은 2; 그 밖에 무엇이 있을까요?


난 당신이 정말 묻고있는 질문은 내가 수학적으로 정확히 2.0를해야 결과가 정확하지를 생산하는 계산을 할 생각 "이지만, 실제로는 약간 덜 생각, 나는 floor에 적용 할 때 그 값은 2.0 대신 1.0이됩니다. 어떻게 방지합니까?"

하나없는 아주 미묘한 질문 사실이다

"오른쪽 "대답은. 당신은 당신이 결과로 무슨 말을하는 건가요 입력 값?

1

편집 - int이 암시 floorf(int)5.95입니다입니다 float에이 대답은 주조 :

옳지 않아 이유에 대한 의견을 읽고. 만약 당신이 그때 그냥 캐스팅 상관 없어 :)

반올림하려는 경우 반올림 후 전혀 캐스팅하지 말아야합니다. (또는 원한다면 캐스팅에 ceilf 캐스팅을 캐스팅해야합니다. (int) (5.9 + 1) '은'6 '- 반올림과 동일). (int)(5.9+0.5)6하지만 (int)(5.4+0.5)5입니다 -

는 0.5 추가, 가장 가까운 반올림합니다. 비록 내가 단지 roundf(5.9)을 사용 하겠지만 :

+8

float에서 int 로의 캐스팅은 암시 적 바닥이 아닙니다. 그것은 C 언어와 몇몇 다른 일반적인 언어들에서, (0을 향한) 절단이다. Floor는 음의 무한대 방향으로 가장 가까운 정수로 반올림됩니다. -3.5를 정수로 변환하면 -3이되지만 floor (-3.5)가 -4가됩니다. –

+0

OK, 그건 공정한 점입니다 - 나는 잘못한 점에 지나치게 단순화했습니다. :) – deanWombourne

18

스위프트 보충 대답을 계산 한 방법

나는 (내가했던 것처럼)를 CGFloatfloorceil을 사용하는 방법을 찾고 여기에 오는 사람들에 대한 보충 답변으로이를 추가하고있다.

var myCGFloat: CGFloat = 3.001 
floor(myCGFloat) // 3.0 
ceil(myCGFloat) // 4.0 

그리고 Int이 필요하면 하나에 캐스트 할 수 있습니다.

var myCGFloat: CGFloat = 3.001 
Int(floor(myCGFloat)) // 3 
Int(ceil(myCGFloat)) // 4 

업데이트

더 이상 C floorceil 기능을 사용할 필요가 없습니다. 스위프트 round()rounding rules과 함께 사용할 수 있습니다.

var myCGFloat: CGFloat = 3.001 
myCGFloat.round(.down) // 3.0 
myCGFloat.round(.up) // 4.0 

원래 변수를 수정하지 않으려면 rounded()을 사용하십시오.

노트 32 비트 및 64 비트 아키텍처와

  • 작품. 사양은 입력 값에 오류가 어떤 결과도 있습니다 값을 반환하는 수 있습니다를 설명이 제공 될 때까지