double 또는 float를 사용해야합니까?


89

C ++에서 다른 하나를 사용하는 것의 장점과 단점은 무엇입니까?


누구든지 float의 배열과 double의 배열을 만들고 실제로 float의 멤버 사이에 4 바이트가 있고 double의 멤버 사이에 8 바이트가 있는지 확인 했습니까? 64 비트 컴파일러 / 컴퓨터는 그렇게 많이 필요하지 않더라도 부동 소수점에 대해 멤버 당 8 바이트를 예약 할 수 있습니다.
user3015682

답변:


104

진정한 답을 알고 싶다면 모든 컴퓨터 과학자가 부동 소수점 산술에 대해 알아야 할 사항을 읽어야 합니다.

요컨대, 표현에서 더 높은 정밀도double허용 하지만 특정 계산의 경우 더 큰 오류가 발생합니다 . "올바른"선택이 될 것입니다 : 많은 정밀도로 사용하기는하지만 더 필요로 하고 올바른 알고리즘을 선택합니다 .

어쨌든 많은 컴파일러는 "비 엄격"모드에서 확장 부동 소수점 연산을 수행합니다 (즉, 하드웨어에서 사용할 수있는 더 넓은 부동 소수점 유형 (예 : 80 비트 및 128 비트 부동) 사용),이 점도 고려해야합니다. 실제로 속도의 차이를 거의 볼없습니다 . 어쨌든 하드웨어의 기본입니다.


10
예. 최신 CPU가 더 크고 더 큰 메모리 청크, 병렬 숫자 처리 장치 및 파이프 라인 아키텍처를 미리 가져 오면 속도 문제는 실제로 문제가되지 않습니다. 당신은 아마보다 숫자의 큰 수량을 처리하는 경우 크기가 4 바이트의 플로트와 8 바이트의 차이를 두 번 수있는 메모리 사용량의 차이를 확인하십시오.
lavinio

5
Well SSE (또는 vertor 부동 소수점 단위)는 배정 밀도에 비해 단 정밀도로 두 배의 플롭 수를 처리 할 수 ​​있습니다. x87 (또는 임의의 스칼라) 부동 소수점 만 수행하는 경우 아마도 중요하지 않을 것입니다.
Greg Rogers

1
@Greg Rogers : 현재 컴파일러는 그렇게 똑똑하지 않습니다. 원시 어셈블리를 작성하지 않는 한 크게 다르지 않습니다. 그리고 예, 이것은 컴파일러가 발전함에 따라 바뀔 수 있습니다.
J-16 SDiZ

추가 참고 사항 : 데이터가 어떻게 생겼는지 전혀 모르는 경우 (또는 링크의 모든 수학에 대한 단서가 전혀없는 double경우) 사용하십시오. 대부분의 경우 더 안전합니다.
J-16 SDiZ

2
이 논문은 짧지 않습니다.
jokoon

45

특별한 이유가 없다면 double을 사용하십시오.

놀랍게도 C (및 C ++)의 "일반"부동 소수점 유형은 double이며 float가 아닙니다. sinlog 와 같은 표준 수학 함수 는 인수로 double을 취하고 double을 반환합니다. 프로그램에서 3.14 를 작성할 때와 같은 일반 부동 소수점 리터럴 은 double 유형을 갖습니다. 플로트가 아닙니다.

일반적인 현대 컴퓨터에서 double은 float만큼 빠르거나 더 빠를 수 있으므로 대규모 계산에서도 성능은 일반적으로 고려할 요소가 아닙니다. (그리고 그것들은 계산이되어야합니다. 그렇지 않으면 성능이 마음에 들지 않아야합니다. 나의 새로운 i7 데스크탑 컴퓨터는 1 초에 60 억 배의 두 배를 할 수 있습니다.)


26

이 질문에는 맥락이 없기 때문에 대답하기가 불가능합니다. 선택에 영향을 미칠 수있는 몇 가지 사항은 다음과 같습니다.

  1. float, double 및 long double의 컴파일러 구현. C ++ 표준은 다음과 같이 설명합니다.

    부동 소수점 유형에는 float, double 및 long double의 세 가지가 있습니다. double 유형은 적어도 float만큼 정밀도를 제공하고 long double 유형은 적어도 double만큼 정밀도를 제공합니다.

    따라서 세 가지 모두 메모리에서 동일한 크기가 될 수 있습니다.

  2. FPU의 존재. 모든 CPU에 FPU가있는 것은 아니며 때로는 부동 소수점 유형이 에뮬레이션되고 때로는 부동 소수점 유형이 지원되지 않는 경우도 있습니다.

  3. FPU 아키텍처. IA32의 FPU는 내부적으로 80 비트입니다. 32 비트 및 64 비트 플로트는로드시 80 비트로 확장되고 저장시 축소됩니다. 4 개의 32 비트 플로트 또는 2 개의 64 비트 플로트를 병렬로 수행 할 수있는 SIMD도 있습니다. SIMD 사용은 표준에 정의되어 있지 않으므로 SIMD를 사용할 수 있는지 확인하기 위해 더 복잡한 분석을 수행하거나 특수 함수 (라이브러리 또는 내장 함수)를 사용해야하는 컴파일러가 필요합니다. 80 비트 내부 형식의 결론은 데이터가 RAM에 저장되는 빈도에 따라 약간 다른 결과를 얻을 수 있다는 것입니다 (따라서 정밀도가 떨어짐). 이러한 이유로 컴파일러는 부동 소수점 코드를 특히 잘 최적화하지 않습니다.

  4. 메모리 대역폭. double이 float보다 더 많은 저장 공간을 필요로하는 경우 데이터를 읽는 데 더 오래 걸립니다. 순진한 대답입니다. 최신 IA32에서는 모든 데이터가 어디에서 오는지에 따라 다릅니다. L1 캐시에있는 경우 데이터가 단일 캐시 라인에서 오는 경우로드는 무시할 수 있습니다. 둘 이상의 캐시 라인에 걸쳐 있으면 약간의 오버 헤드가 있습니다. L2의 경우 시간이 오래 걸리고 RAM에 있으면 더 오래 걸리고 마지막으로 디스크에 있으면 엄청난 시간이 걸립니다. 따라서 float 또는 double의 선택은 데이터가 사용되는 방식보다 덜 중요합니다. 많은 순차 데이터에 대해 작은 계산을 수행하려는 경우 작은 데이터 유형이 바람직합니다. 작은 데이터 세트에 대해 많은 계산을 수행하면 더 큰 데이터 유형을 사용하여 큰 효과를 얻을 수 있습니다. 만약 너라면' 데이터에 매우 무작위로 다시 액세스하면 데이터 크기 선택이 중요하지 않습니다. 데이터는 페이지 / 캐시 라인에로드됩니다. 따라서 RAM에서 1 바이트 만 원하는 경우에도 32 바이트를 전송할 수 있습니다 (시스템 아키텍처에 따라 매우 다름). 무엇보다 CPU / FPU는 수퍼 스칼라 (일명 파이프 라인) 일 수 있습니다. 따라서로드에 여러주기가 걸릴 수 있지만 CPU / FPU는로드 시간을 어느 정도 숨기는 다른 작업 (예 : 곱하기)을 수행 하느라 바쁠 수 있습니다.

  5. 표준은 부동 소수점 값에 대해 특정 형식을 적용하지 않습니다.

사양이있는 경우 최적의 선택을 안내합니다. 그렇지 않으면 무엇을 사용할지 경험해야합니다.


16

Double이 더 정확하지만 8 바이트로 코딩됩니다. float는 4 바이트에 불과하므로 공간과 정밀도가 떨어집니다.

응용 프로그램에 double 및 float가있는 경우 매우주의해야합니다. 나는 과거에 그것 때문에 버그가 있었다. 코드의 한 부분은 float를 사용하고 나머지 코드는 double을 사용했습니다. double을 float로 복사 한 다음 float를 double로 복사하면 큰 영향을 줄 수있는 정밀도 오류가 발생할 수 있습니다. 제 경우에는 화학 공장 이었어요 ... 바라건대 극적인 결과가 없었 으면합니다 :)

아리안 6 로켓이 몇 년 전에 폭발 한 것은 이런 종류의 버그 때문이라고 생각합니다 !!!

변수에 사용할 유형을 신중하게 생각하십시오.


3
float / double의 4/8 바이트는 보장되지 않으며 플랫폼에 따라 다릅니다. 같은 유형일 수도 있습니다 ...
sleske

2
아리안 5 코드는 16 비트 정수로 그 값이 32,767보다 큰 64 비트 부동 소수점을 변환하려고. 이로 인해 로켓이 자체 파괴 시퀀스를 시작하는 오버플로 예외가 발생했습니다. 문제의 코드는 더 오래되고 더 작은 로켓에서 재사용 된 코드였습니다.
cmwt

5

나는 병목 현상이 나타날 때까지 항상 개인적으로 두 배로 간다. 그런 다음 부동으로 이동하거나 다른 부분을 최적화하는 것을 고려합니다.


4

이것은 컴파일러가 double을 구현하는 방법에 따라 다릅니다. double과 float가 같은 유형이되는 것은 합법적입니다 (일부 시스템에 있음).

즉, 실제로 다른 경우 주요 문제는 정밀도입니다. double은 크기 차이로 인해 훨씬 ​​더 높은 정밀도를 갖습니다. 사용하는 숫자가 일반적으로 부동 소수점 값을 초과하는 경우 double을 사용하십시오.

다른 여러 사람들이 성능 문제를 언급했습니다. 그것은 내 고려 사항 목록에서 정확히 마지막이 될 것입니다. 정확성은 귀하의 # 1 고려 사항이어야합니다.



2

나는 차이점에 관계없이 (모든 사람들이 지적했듯이 수레가 더 적은 공간을 차지하고 일반적으로 더 빠릅니다) ... 누군가 double을 사용하여 성능 문제를 겪은 적이 있습니까? 나는 double을 사용한다고 말하고 나중에 "와우, 이것은 정말 느리다"라고 결정하면 ... 성능 병목 현상을 찾으십시오 (아마도 double을 사용한 사실은 아닙니다). 그런 다음 여전히 너무 느리다면 정밀도를 희생하고 float를 사용할 수있는 위치를 확인하십시오.



1

정밀도와 메모리 사이의 가장 확실한 절충점은 CPU에 크게 의존합니다. GB의 RAM을 사용하면 메모리가 문제가되지 않으므로 일반적으로 doubles 를 사용하는 것이 좋습니다 .

성능은 CPU에 크게 의존합니다. floats는 일반적으로 double32 비트 시스템에서 s 보다 더 나은 성능을 얻습니다 . 64 비트에서 doubles는 (일반적으로) 기본 크기이기 때문에 때때로 더 빠릅니다. 그러나 데이터 유형을 선택하는 것보다 훨씬 더 중요한 것은 프로세서에서 SIMD 명령을 활용할 수 있는지 여부입니다.


0

double은 정밀도가 더 높은 반면 float는 메모리를 덜 차지하고 더 빠릅니다. 일반적으로 충분히 정확하지 않은 경우가 아니라면 float를 사용해야합니다.


5
일반적인 현대 컴퓨터에서 double은 float만큼 빠릅니다.
Thomas Padron-McCarthy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.