Math.Floor (Double)가 Double 유형의 값을 반환하는 이유는 무엇입니까?


103

소수 또는 이중에서 왼쪽 정수 값을 가져와야합니다. 예 : 4.6에서 값 4를 가져와야합니다. Math.Floor 함수를 사용해 보았지만 이중 값을 반환합니다. 예 : 4.6에서 4.0을 반환합니다. MSDN 설명서에는 정수 값을 반환한다고 나와 있습니다. 여기에 뭔가 빠졌나요? 아니면 내가 원하는 것을 달성하는 다른 방법이 있습니까?


2
MSDN 설명서에 따르면 정수 값을 반환합니다 . MSDN 설명서 에 Math.Floor는 정수가 아닌 System.Double을 반환합니다.
브로드밴드

정수 은 효과적으로 필요하지만 "int"또는 "long"에 저장할 수 있음을 의미하지는 않습니다. "double"은 "int"보다 훨씬 더 넓은 범위의 모든 정수 값을 성공적으로 저장합니다. 52 초과 : "double"에서 정수 값의 반올림은 2 ^ 52 초과 또는 -2 ^ 52 미만의 정수에 대해 발생할 수 있지만 결과는 여전히 표현 가능한 가장 가까운 정수입니다. "(long) Floor (x)"를 사용하면 변환이 크게 잘못 될 수 있습니다.
verdy_p

그러나 "double"로 표현 될 수있는 정수 값의 유효한 범위는 다음과 같은 절대 값으로 매우 큽니다. (1 + (1 − 2 ^ −52)) × 2 ^ 1023 ≈ 1.7976931348623157E308; "long"으로 2 ^ 63-1 이상입니다. 그러나 "double"은 가수에 대해 52 비트 (저장되지 않고 최상위 비트에 대해 암시 된 1 비트 더하기) 만 있기 때문에 모두 명확하게 저장할 수있는 정수의 범위가 더 제한됩니다. 즉, "double"은 저장 만 가능함을 의미합니다. 절대 값이 2 ^ 53 미만인 경우에만 정수입니다.
verdy_p

안타깝게도 Math.Floor ()는 가능한 경우 "Long"을 사용하여 내부적으로 "Number"유형을 반환하지 않으며, 그렇지 않으면 반올림 된 큰 정수에 대해서만 "Double"을 반환합니다. 그리고 표준 수학 라이브러리는 이러한 통합 변수 번호 유형을 처리하지 않습니다. 지원되는 범위 나 정밀도의 손실없이 압축 십진수 또는 이진수로 인코딩 된 Long, Double 또는 큰 정수를 포함하여 통합 숫자 유형을 구현하는 다른 수학 라이브러리가 있습니다.
verdy_p

답변:


146

의 범위는 또는 double의 범위보다 훨씬 넓습니다 . 이 코드를 고려하십시오.intlong

double d = 100000000000000000000d;
long x = Math.Floor(d); // Invalid in reality

정수가 범위를 벗어났습니다. long그러면 어떤 일이 발생할 것으로 예상합니까?

일반적으로 값이 실제로int 또는 범위 내에 있다는 것을 알고 long있으므로 캐스트합니다.

double d = 1000.1234d;
int x = (int) Math.Floor(d);

하지만 그 캐스트에 대한 책임은 그 Math.Floor자체가 아니라 개발자에게 있습니다. 범위를 벗어난 모든 값에 대해 예외로 실패하도록 만드는 것은 불필요하게 제한적이었을 것입니다 long.


2
Floor는 double의 정수 표현을 반환하고 과학적 계산을 위해 double을 반환합니다. double에는 64 비트가 있고 long에도 64 비트가 있기 때문에이 대답은 올바르지 않지만 double은 올바르게 저장할 수 있더라도 하위 유효 비트의 정확한 자릿수를 저장할 수 없습니다. 오래.
Akash Kava

1
@Jon : C #에서 양수를 음수로 만드는 방법에 대한 논쟁에 왜 참여하지 않았습니까? : stackoverflow.com/questions/1348080/…
MusiGenesis

3
@Jon : 천천히하세요. 커뮤니티는 양수에 -1을 곱하면 음수가된다는 사실을 발견했습니다. 모두 StackOverflow에서 잘 작동합니다.
MusiGenesis

1
@javapowered : 아니요, (int) 15.0은 0 이 아닙니다. 다른 문제가 발생했지만 그 결과를 알 수 없습니다. 이를 시연하는 짧지 만 완전한 프로그램을 만든 다음 질문하십시오. 난 당신이 열심히 재현 찾을 수 있습니다 의심 ...
존 소총

1
@MusiGenesis : <code> (int) IGNORE_RATIO * Volume </ code>은 <code> (int) 0.15 * Volume </ code>으로 계산되지만 typecast는 제품의 결과가 아닌 비율에만 적용됩니다. 당신은 <code> 0 * Volume </ code> 즉 0을 얻습니다! 대신 <code> (int) (IGNORE_RATIO * Volume) </ code>을 사용하여 버그를 해결하십시오.
verdy_p

11

MSDN에 따르면 Math.Floor (double)은 double을 반환합니다. http://msdn.microsoft.com/en-us/library/e0b5f0xb.aspx

int로 원하는 경우 :

int result = (int)Math.Floor(yourVariable);

MSDN 기사가 오해의 소지가있는 방법을 알 수 있습니다. 결과가 "정수"(이 경우 정수를 의미 함)이지만 여전히 TYPE Double임을 지정해야합니다.


당신의 답변에 감사드립니다. 실제로 나는이 기사를보고 있었다 : msdn.microsoft.com/en-us/library/e0b5f0xb.aspx 그러나 어쨌든, 나는 당신의 제안을 시도 할 것입니다. 감사합니다.

사실, 상단에 "정수를 반환"이라고 말하지만 그 아래에 유형이 지정되어 있습니다. public static double Floor (double d)
Neil N

3
정수! = int( answers.com/integer)- 정수 저장할 있으며 Double(Jon의 답변 참조) int.
Shog9

쇼그, 나는 그들이 할 수 없다고 말하지 않았다. 내가 말한 것은 "아직도 TYPE Double"입니다.
Neil N

1
@Neil : 맞습니다- "정수"(집합 int이름 )와 (유형 이름 )의 차이를 강조하고 싶었습니다 .
Shog9

4

숫자의 정수 부분 만 필요하면 숫자를 int. 이것은 소수점에서 숫자를 자릅니다.

double myDouble = 4.6;
int myInteger = (int)myDouble;

2
음수의 경우 int로 캐스팅 은와 다르게 작동 한다는 점에 유의하십시오 Floor. Floor캐스트는 항상 가장 음수로 자릅니다. 반면에 캐스팅하면 int0으로 자릅니다.
Magnus


0

Floor는 더블로 남겨 두므로 더 많은 더블 계산을 할 수 있습니다. int로 원하면 floor의 결과를 int로 캐스팅하십시오. 음수에 대한 바닥 규칙 (IIRC)이 다르기 때문에 원래 double을 int로 캐스팅하지 마십시오.


0
Convert.ToInt32(Math.Floor(Convert.ToDouble(value)))

이것은 출력으로 4.6반환 하면 원하는 정확한 값을 제공합니다 4.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.