문제

나는 질문이 이상한 것 같다. 프로그래머는 때때로 너무 많이 생각합니다. 읽어주세요 ...

CI 사용에서 signed 그리고 unsigned 정수가 많이 있습니다. 서명되지 않은 변수에 서명 된 정수를 할당하는 것과 같은 작업을 수행하면 컴파일러가 경고한다는 사실이 마음에 듭니다. 서명되지 않은 정수와 훨씬 더 많은 서명을 비교하면 경고를받습니다.

나는이 경고를 좋아한다. 그들은 내 코드를 올바르게 유지하는 데 도움이됩니다.

수레에 대해 똑같은 사치를 가지지 않는 이유는 무엇입니까? 정사각형 root는 확실히 음수를 반환하지 않을 것입니다. 부정적인 플로트 값이 의미가없는 다른 장소도 있습니다. 서명되지 않은 플로트를위한 완벽한 후보.

BTW- 나는 부유물에서 부호 비트를 제거함으로써 얻을 수있는 단일 추가 정밀도에 대해 정말로 열중하지 않습니다. 나는 매우 행복합니다 float그들은 지금있는 것처럼. 그냥하고 싶어요 서명되지 않은 상태로 플로트를 표시하십시오 때로는 정수와 함께 얻는 것과 같은 종류의 경고를 얻습니다.

나는 부호없는 부동 소수점 번호를 지원하는 프로그래밍 언어를 모릅니다.

그들이 왜 존재하지 않는지 아십니까?


편집하다:

X87 FPU는 부호없는 플로트를 다루는 지침이 없다는 것을 알고 있습니다. 서명 된 플로트 지침 만 사용하겠습니다. 오용 (예 : 제로 이하로가는)은 서명 된 정수의 오버플로가 정의되지 않은 것과 같은 방식으로 정의되지 않은 동작으로 간주 될 수 있습니다.

도움이 되었습니까?

해결책

C ++가 부호없는 플로트를 지원하지 않는 이유는 CPU가 실행할 동등한 기계 코드 작업이 없기 때문입니다. 따라서 그것을 지원하는 것은 매우 비효율적입니다.

C ++가 그것을 지원했다면, 때로는 서명되지 않은 플로트를 사용하고 성능이 방금 죽었다는 것을 깨닫지 못할 것입니다. C ++가 지원되면 모든 부동 소수점 조작은 서명되었는지 아닌지 확인해야합니다. 그리고 수백만 건의 부동 소수점 운영을 수행하는 프로그램의 경우 이는 허용되지 않습니다.

따라서 문제는 하드웨어 구현자가이를 지원하지 않는 이유입니다. 그리고 그에 대한 답은 원래 정의되지 않은 플로트 표준이 없다는 것입니다. 언어는 거꾸로 호환되는 것을 좋아하기 때문에 언어가 추가 되었더라도 언어를 사용할 수 없습니다. 부동 소수점 사양을 보려면 IEEE 표준 754 플로팅 포인트.

부유물을 캡슐화하거나 음수로 전달하려고하면 경고를 던지는 서명되지 않은 플로트 클래스를 만들어 서명되지 않은 부동 소수점 유형을 가질 수 있습니다. 이것은 덜 효율적이지만, 아마도 당신이 그것들을 사용하지 않으면 강렬하게 사용하지 않으면 약간의 성능 손실에 신경 쓰지 않을 것입니다.

나는 서명되지 않은 부유물을 가진 유용성을 분명히 본다. 그러나 C/C ++는 안전보다 모든 사람에게 가장 적합한 효율성을 선택하는 경향이 있습니다.

다른 팁

C/C ++에서 서명 된 정수와 서명되지 않은 정수 사이에는 큰 차이가 있습니다.

value >> shift

서명 된 값은 상단 비트를 변하지 않은 상태로두고 (부호 확장), 서명되지 않은 값은 상단 비트를 제거합니다.

서명되지 않은 플로트가없는 이유는 음수 값이 없으면 모든 종류의 문제를 신속하게 빠르게 만났기 때문입니다. 이걸 고려하세요:

float a = 2.0f, b = 10.0f, c;
c = a - b;

C는 어떤 가치가 있습니까? -8. 그러나 그것이 음의 숫자가없는 시스템에서 무엇을 의미 할 것인가. float_max -8 아마도? 실제로, 이것은 정밀 효과로 인해 float_max -8이 float_max로 작동하지 않으므로 상황이 훨씬 더 쉬워집니다. 더 복잡한 표현의 일부라면 어떨까요?

float a = 2.0f, b = 10.0f, c = 20.0f, d = 3.14159f, e;
e = (a - b) / d + c;

이것은 2의 보완 시스템의 특성으로 인해 정수에게는 문제가되지 않습니다.

또한 표준 수학적 함수를 고려하십시오 : sin, cos 및 tan은 입력 값의 절반에만 작동하며 값의 로그를 찾을 수 없습니다. bb -4.ac)) / 2.a 등. 실제로, 이것은 어딘가에 음수 값을 사용하는 다항식 근사치로 구현되는 경향이 있기 때문에 복잡한 기능에 대해서는 작동하지 않을 것입니다.

따라서 서명되지 않은 수레는 쓸모가 없습니다.

그러나 범위 범위를 확인하는 클래스가 플로트 값을 확인하는 클래스가 유용하지 않다고 말하는 것은 아닙니다. 예를 들어 RGB 계산과 같은 주어진 범위로 값을 클램핑 할 수 있습니다.

(옆으로, Perl 6은 당신이 쓸 수 있습니다

subset Nonnegative::Float of Float where { $_ >= 0 };

그런 다음 사용할 수 있습니다 Nonnegative::Float 다른 유형처럼.)

서명되지 않은 부동 소수점 작업에 대한 하드웨어 지원은 없으므로 C는 제공하지 않습니다. C는 주로 "휴대용 어셈블리"로 설계되었습니다. 즉, 특정 플랫폼에 묶이지 않고 금속에 가깝습니다.

편집하다

C는 어셈블리와 같습니다. 당신이 보는 것은 정확히 당신이 얻는 것입니다. 암시 적 "이 플로트가 당신에게 무분별하지 않은지 확인하겠습니다"는 디자인 철학에 위배됩니다. 정말로 원한다면 추가 할 수 있습니다 assert(x >= 0) 또는 유사하지만 명시 적으로 그렇게해야합니다.

서명되지 않은 INT는 서명 된 INT가 제공 할 수있는 것보다 더 큰 가치 마진이 필요하기 때문에 만들어 졌다고 생각합니다.

플로트는 마진이 훨씬 큽니다. 서명되지 않은 플로트에 대한 '물리적'요구는 없었습니다. 그리고 당신이 당신의 질문에서 자신을 지적 할 때, 추가 1 비트 정밀도는 죽일 것이 아닙니다.

편집하다:읽은 후 Brian R. Bondy의 답변, 나는 내 대답을 수정해야한다 : 그는 기본 CPU에 서명되지 않은 플로트 작업이 없다는 것이 확실히 옳다. 그러나, 나는 이것이 위에서 언급 한 이유에 근거한 설계 결정이라는 믿음을 유지합니다. ;-)

TREB가 올바른 길을 가고 있다고 생각합니다. 서명되지 않은 해당 유형이있는 정수에 더 중요합니다. 그것들은 사용되는 것입니다 비트 변화 그리고 사용됩니다 비트 맵. 사인 비트가 방해가됩니다. 예를 들어, 음의 값을 오른쪽으로 이동하면 결과 값은 C ++에 정의 된 구현입니다. 서명되지 않은 정수 또는 넘치는 정수로 그렇게하는 것은 그러한 비트가 없기 때문에 시맨틱을 완벽하게 정의했습니다.

따라서 정수의 경우 적어도 별도의 서명되지 않은 유형의 필요성은 단순히 경고를 제공하는 것보다 강합니다. 위의 모든 지점을 플로트에 대해 고려할 필요는 없습니다. 따라서 하드웨어 지원이 실제로 필요하지 않으며 C는 이미 그 시점에서이를 지원하지 않을 것입니다.

IEEE 플로팅 포인트 사양 사양에만 서명하고 대부분의 프로그래밍 언어가 사용한다고 생각합니다.

IEEE 플로팅 포인트 번호에 Wikipedia Articla

편집 : 또한 다른 사람들이 언급 한 바와 같이, 대부분의 하드웨어는 비 음성 플로트를 지원하지 않으므로 하드웨어 지원이 있기 때문에 정상적인 종류의 플로트가 더 효율적입니다.

정사각형 root는 확실히 음수를 반환하지 않습니다. 부정적인 플로트 값이 의미가없는 다른 장소도 있습니다. 서명되지 않은 플로트를위한 완벽한 후보.

C99는 복소수 및 일반적인 형태의 SQRT를 지원합니다. sqrt( 1.0 * I) 부정적입니다.


주석가들은 내가 유형의 유형을 언급하고 있다는 점에서 위의 약간의 광택을 강조했다. sqrt 함수가 아닌 매크로, 복합체를 실제 구성 요소로 잘라서 스칼라 부동 소수점 값을 반환합니다.

#include <complex.h>
#include <tgmath.h>

int main () 
{
    complex double a = 1.0 + 1.0 * I;

    double f = sqrt(a);

    return 0;
}

또한 모든 복소수의 SQRT의 실제 부분은 양수 또는 0이고 SQRT (1.0*I)는 SQRT (0.5) + SQRT (0.5)*i가 아니기 때문에 뇌 분파가 포함됩니다.

주된 이유는 서명되지 않은 부유물이 서명되지 않은 INT에 비해 실제로 용도가 제한되어 있기 때문입니다. 하드웨어가 지원하지 않기 때문이라는 주장을 사지 않습니다. 오래된 프로세서에는 부동 소프트웨어 기능이 전혀 없었으며 소프트웨어에서 모두 모방되었습니다. 서명되지 않은 플로트가 유용하다면 소프트웨어에서 먼저 구현되었을 것이고 하드웨어는 그에 따라 갔을 것입니다.

C의 서명되지 않은 정수 유형은 추상 대수 고리의 규칙에 순종하는 방식으로 정의됩니다. 예를 들어, 모든 값 x와 y의 경우 xy를 Y에 추가하면 X를 산출합니다. 서명되지 않은 정수 유형은 다른 숫자 유형 (또는 서명되지 않은 다른 크기)으로 전환하지 않는 모든 경우에 이러한 규칙을 준수해야합니다. 그리고 그 보증은 그러한 유형의 가장 중요한 기능 중 하나입니다. 경우에 따라 서명되지 않은 유형 만 제공 할 수있는 추가 보증과 대가로 마이너스 숫자를 나타내는 능력을 포기하는 것이 좋습니다. 서명 여부에 관계없이 플로팅 포인트 유형은 대수 고리의 모든 규칙을 준수 할 수 없습니다. 동등성 클래스 [특정 값이 자신과 비교하여 비교하도록 요구함으로써]. 나는 "서명되지 않은"부동 소수점 유형이 평범한 부동 소수점 유형이 할 수없는 공리를 준수 할 수 없다고 생각합니다.

C 컴파일러를 대상으로 한 기본 프로세서는 부호없는 부동 소수점 번호를 다루는 좋은 방법이 없기 때문입니다.

ihmo 하드웨어 나 소프트웨어에서 서명 된 부동산 지점 유형을 모두 지원하는 것은 너무 귀찮을 것입니다.

정수 유형의 경우 사용할 수 있습니다 그만큼 같은 논리 단위 서명 된 정수 작업과 서명되지 않은 정수 작업 대부분의 상황에서 2의 보완의 멋진 속성을 사용하는 경우 그 경우 결과는 동일합니다 추가, 서브, 비 확장 MUL 및 대부분의 비트 작업. 서명 된 버전과 서명되지 않은 버전을 구별하는 작업의 경우 여전히 논리의 대부분을 공유하십시오. 예를 들어

  • 산술 및 논리적 이동은 최고 비트에 대한 필러의 약간의 변화 만 있으면됩니다.
  • 곱하기 확대 곱하기는 기본 부분에 동일한 하드웨어를 사용할 수 있으며 몇 가지 별도의 논리를 사용하여 조정할 수 있습니다. 결과는 징후를 바꾸는 것입니다. 실제 승수에 사용 된 것은 아니지만 가능합니다.
  • 서명 된 비교는 서명되지 않은 비교로 변환 될 수 있으며 상단 비트를 토글하거나 첨가 INT_MIN. 또한 이론적으로 가능하면 하드웨어에 사용되지는 않지만 유용합니다. 한 가지 유형의 비교 만 지원하는 시스템 (8080 또는 8051 예 :)

1의 보완을 사용하는 시스템은 단순히 가장 중요한 비트로 포장 된 캐리 비트이기 때문에 논리에 약간의 수정이 필요합니다. 부호-매거 시스템에 대해서는 확실하지 않지만 내부적으로 1의 보완을 사용하십시오 따라서 같은 것이 적용됩니다

안타깝게도 우리는 부동 소수점 유형에 대한 사치가 아닙니다. 간단히 표시 비트를 풀면 서명되지 않은 버전이 있습니다. 그러나 우리는 그 비트를 무엇에 사용해야합니까?

  • 지수에 추가하여 범위를 늘리십시오
  • Mantissa에 추가하여 정밀도를 높이십시오. 일반적으로 범위보다 더 정밀도가 필요하기 때문에 이것은 종종 더 유용합니다.

그러나 두 선택 모두 필요합니다 더 큰 가산기 더 넓은 값 범위를 수용합니다. 이는 가산기의 상단 비트가 대부분 사용되지 않은 상태에서 논리의 복잡성을 증가시킵니다. 곱셈, 분할 또는 기타 복잡한 작업에는 더 많은 회로가 필요합니다.

소프트웨어 플로팅 포인트를 사용하는 시스템에서는 시간 동안 예상되지 않은 각 기능에 대해 2 버전이 필요하거나 서명되지 않은 기능의 일부를 공유 할 수있는 "까다로운"방법을 찾아야합니다.

하지만 C가 발명되기 오래 전에 부동 소수점 하드웨어가 존재했습니다, 그래서 나는 C의 선택이 위에서 언급 한 이유 때문에 하드웨어 지원이 부족했기 때문이라고 생각합니다.

즉, 여러 가지가 있습니다 전문 서명되지 않은 부동 소수점 형식, 주로 이미지 처리 목적으로 Khronos Group의 10 및 11 비트 부동 소수점 유형

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top