세 개의 작은 숫자를 하나의 두 배에 저장하는 방법은 무엇입니까? (How to store three small numbers into one double?)


문제 설명

세 개의 작은 숫자를 하나의 두 배에 저장하는 방법은 무엇입니까? (How to store three small numbers into one double?)

I have int A, B, C. And A is in range 0‑9999B is 0‑99C is 0‑99.

Because the function must return only one double, I think of putting them all into one number. Otherwise I need to call function three times. But I cannot write an efficient code to do this. This will be called millions times, so it should be quite effective, but no ASM.

I need a function double pack3int_to_double(int A, int B, int C) {}


참조 솔루션

방법 1:

Couldn't you just store A + 1000B + 100000C?

For example, if you wanted to store A = 1234, B = 6, and C = 89, you'd just store

89061234
CCBAAAA

You can then extract the numbers by casting the double to an int and using standard integer division and modulus tricks to recover the individual values.

Hope this helps!

방법 2:

If A<10,000 and B & C <100, A can be expressed with 14 bits, and B & C with 8 bits. Thus you need 30 bits in total. You could therefore pack/unpack the integers by shifting it to the right place:  

int packed = A + B<<14 + C<<22;  
A = packed & 0x3FFF; B = (packed >> 14) & 0xFF; C = (packed >> 22) & 0xFF;

Bit shifting is of course MUCH faster than multiply/divide, and you can cast the int to a double and vice versa.

방법 3:

This is technically not legal C code, so you would use this at your own risk:

typedef union {
    double x;
    struct {
        unsigned a : 14;
        unsigned b : 7;
        unsigned c : 7;
    } y;
} result_t;

The C standard doesn't allow using a union member to write a value and a different one to read it out, but I am not aware of a compiler that does the static analysis to diagnose such a problem (it doesn't mean one won't do so in the future).  Also, using certain int values may result in a trap representation for a double. But, if you know your system will not generate any trap representations, you can consider using this.

double pack3int_to_double(int A, int B, int C) {
    result_t r;
    r.y.a = A;
    r.y.b = B;
    r.y.c = C;
    return r.x;
}

void unpack3int_from_double (double X, int *A, int *B, int *C) {
    result_t r = { X };
    *A = r.y.a;
    *B = r.y.b;
    *C = r.y.c;
}

방법 4:

You can use out parameters in function call and retrieve all 3 int variables.

방법 5:

You could return a NaN double with the data stored in the mantissa. That gives you 53 bits to utilize. Should be plenty. 

http://en.m.wikipedia.org/wiki/NaN

(by exebooktemplatetypedefReinhard MännerjxhPritesh TayadeStilesCrisis)

참조 문서

  1. How to store three small numbers into one double? (CC BY‑SA 3.0/4.0)

#optimization #double #math






관련 질문

세 개의 작은 숫자를 하나의 두 배에 저장하는 방법은 무엇입니까? (How to store three small numbers into one double?)

중첩 최적화에서 솔루션을 반환하는 방법은 무엇입니까? (How to return solutions in a nested optimization?)

C에서 "signed int"가 "unsigned int"보다 빠른 이유는 무엇입니까? (In C, why is "signed int" faster than "unsigned int"?)

값이 없는 경우 HTML5 로컬 저장소 개체는 무엇을 반환합니까? (What does the HTML5 Local Storage object return if there is no value?)

200K 게시물이 있는 Wordpress 사이트는 JOIN이 느린 SQL_CALC_FOUND_ROWS를 게시합니까? 속도 최적화? (Wordpress site with 200K posts SQL_CALC_FOUND_ROWS with JOINs slow? Optimize for speed?)

xlx의 각 시트에서 특정 셀을 추출하기 위해 이 R 코드를 개선하는 데 도움이 필요합니다. (I need help to improve this R code to extract specific cell from each sheet in xlxs)

이 for 루프에서 fminunc가 매번 동일한 결과를 제공하는 이유는 무엇입니까? (Why is fminunc in this for loop giving the same result each time?)

정수 스칼라 배열만 Hyperopt에서 스칼라 인덱스 오류로 변환될 수 있습니다. (only integer scalar arrays can be converted to a scalar index error in Hyperopt)

벡터 병합 알고리즘 도움말 (Help with algorithm for merging vectors)

이 MIPS 프로그램이 이렇게 오래 걸리나요? (파이에 가까운 프로그램) (Is this MIPS program supposed to take this long? (program that approximates pi))

힘을 최소화하기 위한 최적의 궤적, 최종 조건 문제 (Optimal trajectory to minimize force, issues with final conditions)

단일 svg 요소를 만들기 위해 여러 모양 병합 (Merging number of shapes to make a single svg element)







코멘트