2012-05-25 5 views
0

double의 int 쌍을 인코딩하고 싶습니다. 예를 들어 내가 함수 통과 싶어 말 :여러 개의 int를 double로 인코딩하기

foo(int a, int b) 

을 대신 I (예) 한 번 두의 int를 대표 할 :

foo(double aAndB) 

은 현재 내가 하나 개 INT를함으로써 그 일을하고있다 소수점의 한쪽 (즉, 10과 15는 10.15가됩니다)을 문자열 스트림 토큰 화로 변환하고 두 개의 숫자를 추출합니다.

그러나 10과 10 같은 숫자에 있어서는 분명히 결함이 있습니다. 즉 10.1이됩니다.

몇 가지 까다로운 수학적 방법을 통해이 작업을 수행 할 수있는 방법이있어서 2 int를 나타내는 double 함수를 전달할 수 있습니까?

감사합니다.

+2

왜 그렇게할까요? –

+0

이것으로 무엇을 이루고자합니다. 질문에'encoding'이라는 태그가 붙어 있기 때문에, 어느 시점에서 두 개의 int를 되찾기 위해 double을 해독하려고한다고 가정합니다. 이 경우 엔코딩을 잃어 버리지 않으시겠습니까? – Vikas

+0

@Paolo 1. 흥미로운 질문입니다. 2. 왜냐하면 나는 double을 취하고 2 개의 ints를 전달해야하는 팩토리 메소드를 가진 추상화 된 타입을 가지고 있기 때문이다. –

답변

5

, 방금 예를 들어, 직접 배에 비트를 저장할 수 있다고 생각하는 것 :

int32_t i1 = rand(); 
int32_t i2 = rand(); 
int64_t x = (((int64_t)i1)<<32) | ((int64_t)i2); 
double theDouble; 
memcpy(&theDouble, &x, sizeof(theDouble)); 

을 ... 그렇게하는 것은 "거의 효과가 있습니다". 즉, i1 및 i2의 가능한 많은 값에 대해서는 정상적으로 작동하지만 모두에 대해서는 그렇지 않습니다.특히 IEEE754 부동 소수점 형식의 경우 지수 비트가 0x7ff로 설정된 모든 값은 "NaN"을 나타내는 것으로 처리되며 부동 소수점 하드웨어는 다른 NaN 상당 비트 패턴을 해당 기본 설정으로 다시 변환 할 수 있습니다. 인수로 double을 전달할 때 NaN 비트 패턴.

두 개의 32 비트 정수를 두 개로 채우는 것은 대부분의 경우 작동하는 것처럼 보일 수 있지만 가능한 모든 입력 값으로 테스트하면 값이 예기치 않게 두 번 내부에 머물렀을 때 돌연변이가 발생하여 다시 해독 할 때 다른 값으로 나온 경우도 있습니다.

물론이 경우에는 double의 가수 비트를 설정하는 데주의해야하지만이 경우 정수 당 26 비트 만 제공하므로 +/- 정수 값만 저장할 수 있습니다. 33,554,432 정도입니다. 유스 케이스에 따라 괜찮을 수도 있습니다.

제 조언은 당신이하려는 일을하는 다른 방법을 찾아야한다는 것입니다. 부동 소수점 변수에 부동 소수점 데이터를 저장하는 것은 문제를 요구하고 있습니다. 특히 코드를 이식성있게 만들려면 더욱 그렇습니다.

3

두 배는 정확히 53 비트까지의 정수를 나타낼 수 있습니다. 26 비트 및 27 비트 정수를 유지하려는 경우 매우 간단합니다. double combined = bits27*67108864.0 + bits26;

67108864는 2^26입니다. 운이 좋다하고 INT는이 같은의 int를 저장할 수의 절반 이중 경우

4

:

 
int a = 10; 
int b = 20; 
double d; 

*(int *)&d = a; 
*((int *)&d + 1) = b; 

int outa = *((int *)&d); 
int outb = *(((int *)&d) + 1); 
printf("%d %d\n", outa, outb); 

이것은 일반적으로/휴대 성을 작동하지 않습니다. double과 int의 비트 수가 같으면 불가능합니다.

+0

이것은 32 비트에서 작동합니다. 그러나 사용자 85509는 이식성이 없습니다. 그러나 32 비트 정수형으로 제한하더라도 (헤더가있는 헤더가 있음) - 필요하면 잘못된 디자인을 나타내는 기호입니다. –

1

은 다음과 같이 노동 조합을 정의하려고 :

struct two_int { 
    int a; 
    int b; 
}; 

union encoding { 
    struct two_int a; 
    double c; 
}; 

그러나이 같은 일을하는 것은 이식성 문제를 초래할 수있다. 귀하의 경우에 적절한 방법을 두 번 확인하십시오.

1

바이너리 마스크를 사용하고 "double"에서 정보를 추출 할 수 있습니다. 예를 들어

:

double encode(int a, int b) 
{ 
    double d = 0; 
    d = d | a; 
    d = d | (b << 8); 
    return d; 
} 

double decode(double d) 
{ 
    a = d & 0xFF; 
    b = (d >> 8) & 0xFF; 
} 

인코딩 부에서,이 두 변수 (D)의 하위 8 비트에있을 것, (B)는 (D)의 상위 8 비트가 될 것이다.

0

이 매개 변수에 항상 두 개의 int를 전달하는 경우에는 double을 전달할 수 없습니다. 대신 두 개의 int를 별도의 int로 전달하거나 구조체에 래핑하십시오.

당신이 그것을하는 방식은 당신이 진정한 더블과 두 개의 int 사이의 차이를 감지 할 수있는 기회를 남기지 않습니다. 따라서 위에서 설명한 내용을 수행하여 기능을 잃지 않을 것이라고 결론을 내 렸습니다. (일반적으로) 두 번이 64 비트가 각 INT가 32 비트를 가지고 있기 때문에

+0

이 질문에 대한 답변이 아닙니다. 충고에 감사하지만 나는 지금 당장이 방법을 시도하고있다. –

+0

공장 인터페이스를 제어 할 수 있다면 그는이 작업을 수행해야합니다. – RedX

+0

@Ben 듣고 싶은 대답이 아닐지 모르지만 문제의 해결책 일 가능성이 높습니다. –