contact 머드클럽 문의하기 카카오톡
즐겨찾기 추가plus 머드클럽이 새롭게 오픈하였습니다!
sub image
신세계 64비트 난수 처리
member photo 성천사 0 150 0 2025-01-01 21:19:11

VC6.0 에서 32비트는 문제 없이 난수가 생성이 가능한데, int 형을 초과한 난수생성이 불가능 하다는 것을 알고 이런 저런 시도를 해 보았습니다. 시도를 한것이 __int64 number64(__int64 min, __int64 max) 의 gset_73_3 == 0 이고, 이 조잡한 코드는 최소치의 제한이 있는(아마도 1%) 코드입니다.  그래서 고민고민하다 시도를 한 것이 gset_73_3 == 1 이고, 이것은 32비트 * 32비트는 64 비트 인 것을 참고해서 실수형 난수 생성 함수 double db_number(double from, double to)  함수와 최종 난수 생성 후 수치 return 용 _int64 _number64(__int64 from, __int64 to) 함수, 그리고 number64 로 입력받은 최소 최대치의 제곱근을 구해 return 하는 double number_split(__int64 num_split, int opt) 함수를 만들어 적용을 했습니다.  단순히 흉내내기용 입니다만 VC6.0 에서 사용가능한 64비트 난수생성 코드를 찾을 수도 없어서 만들었습니다.  일단 작동은 한다는데 의의를 두고 있습니다.  물론 좀 더 높은 버전의 개발도구를 사용한다면 이런것들은 다 쓸모 없습니다.

 

number64() 안의 gset_73_3 은 제 머드에만 있는 설정 변수 이기 때문에 다른 머드에서는 else {} 부분만을 떼어 쓰면 됩니다.

 

__int64 number64(__int64 min, __int64 max)
{
    __int64 _number64(__int64 from, __int64 to);
    extern __int64 max64;
    extern int fullint; 
    int m = 0, endint = 0;
    __int64 a = 0, c = 0, e = 0, f = 0, g = 0, temp = 0;
    double b = 0, h = 0, l = 0, n = 0, o = 0;
    char ranumber[MAX_INPUT_LENGTH]="";

    if (gset_73_3 == 0) { // 난수처리(외부오설정)
        if (min == max)
            return max;

        if (max < fullint) {
_number64_to_number:
            endint = number((int)min, (int)max);
            return endint;
        }

        if (max < 1)
            return 0;

        h = (double)(e = min);
        l = (double)(f = max);
        g = (__int64)(f * 0.01);
        a = (__int64)((e < g) ? 1 : ((h / l) * 100));
        m = (int)a;
        b = number(m, 100);
        c = (__int64)(f * (o = ((b < 1) ? (b + 1) : (b * 0.01))));
        if (c < e)
            c = e;
        else if (c > f)
            c = f;
        return c;
    } else {
        // 난수처리에 sqrt 사용
        if (min > max) {                  // 최소값이 최대값보다 크면
            temp = min;                   // 최소값을 temp 로
            min = max;                    // 최소값에 최대값을 넣고
            max = temp;                   // 최대값에 temp 넣기
        }

        if (max <= fullint || (max <= 0)) // 최대값이 fullint (2147483647) 이하라면
            goto _number64_to_number;     // 73_3 == 0 안의 number() 로 처리

        sprintf(ranumber, "%I64d", _number64(min, max));
        return _atoi64(ranumber);
    } 
}

 

double db_number(double from, double to) 
{
    double tmp;

    if (from > to) {
        tmp = from;
        from = to;
        to  = tmp;
    }

    return (rand() / (double)RAND_MAX) * (to - from) + from;

}

 

// VC 6.0 에는 없는 64비트 난수 처리로 인해 32비트 이상의 난수 발생이 불가능 해
// 입력받은 값을 sqrt 를 사용해 int * int 를 해서 계산 후 출력. 64비트 난수 생성을 흉내낸 코드
// 2024-05-26, 최종 2025-01-01
__int64 _number64(__int64 from, __int64 to)
{
    double db_number(double from, double to);
    extern int maxint;
    int number(int from, int to);
    double number_split(__int64 num_split, int opt);
    double fromfirst = 0.0, fromsecond = 0.0, tofirst = 0.0, tosecond = 0.0;
    double calc1 = 0.0, calc2 = 0.0, last = 0.0;
    int normal = 0;

 

    if (from <= maxint && to <= maxint) {
        normal = number((int)from, (int)to);
        return normal;
    }

 

    // 입력한 최소값에 대한(from) 제곱근 계산
    // 64 비트는 32 비트 * 32 비트 이므로
    // 최소값을 절반으로 나눈 값의 제곱근을 fromfirst 에 넣는다. 옵션 0
    // 나머지 절반의 값을 fromsecond 에 넣는다. 옵션 1
    // 이후 최대값도 같은 방식으로 제곱근을 얻어 number() 함수를 사용해 
    // int 크기의 최소, 최대 제곱근 사이의 난수를 구해
    // 최종적으로 발생한 최소 최대의 난수를 곱한 값에 2 를 곱해 
    // 64 비트의 난수를 얻는다.
    
    // 최소값 from
    fromfirst = number_split(from, 0);
    fromsecond = number_split(from, 1);

 

    // 최대값 to
    tofirst = number_split(to, 0);
    tosecond = number_split(to, 1);

 

    // 합산
    calc1 = db_number(fromfirst, tofirst);
    calc2 = db_number(fromsecond, tosecond);
    last = (calc1 * calc2) * 2;
    return (__int64)last;
}

 

double number_split(__int64 num_split, int opt)
{
    __int64 split = num_split;
    double first = sqrt((double)split / 2.0);
    double second = split / (2.0 * first);

 

    if (opt == 0) {
        return first;
    } else if (opt == 1) {
        return second;
    }
    return 0.0;
}

 

0
정회원 이상만 코멘트 사용이 가능합니다.
총 게시물 29개 / 검색된 게시물: 29개
글번호   제목 작성자 조회수 싫어요 작성일
29 TBAMUD 한글 아이디 저장 함수 성천사 88 0 0 2025-03-29
28 신세계 64비트 난수 처리 성천사 151 0 0 2025-01-01
27 접속금지, 접속허용 편의성 수정 성천사 179 0 0 2024-10-27
26 신세계 텍스트 출력 [1] 성천사 208 0 0 2024-08-06
25 신세계 시체생성 성천사 179 0 0 2024-06-12
24 삭제된 게시물입니다. 성천사 124 0 0 2024-06-12
23 신세계 C to VC6.0 성천사 348 0 0 2024-03-07
22 신세계 장비위치 구하기 성천사 202 0 0 2024-03-04
21 신세계 파일 존재여부 확인 성천사 264 0 0 2024-02-18
20 신세계 맙타입 전투 성천사 295 0 0 2023-12-02
19 신세계 addlog() 성천사 247 0 0 2023-10-25
18 신세계 캐릭터, 맙 이동 코드 성천사 254 0 0 2023-10-25
17 신세계 지정번호의 물건 찾기및 제거하기 성천사 358 0 0 2023-05-07
16 신세계 이동물건 [1] 성천사 621 0 0 2022-12-30
15 신세계 날씨변경 명령어 성천사 421 0 0 2022-12-25
14 [circle] 신세계 운영자 명령어 방청소 성천사 476 0 0 2022-10-08
13 [circle] 신세계 물건이름 성천사 512 0 0 2022-08-26
12 [circle] 신세계 공격대상 성천사 535 0 0 2022-08-19
11 [circle] 미확인장소 물건 수거 성천사 1015 0 0 2019-09-23
10 [circle] 신세계 포탈과 이동 명령어 [1] 성천사 1452 0 0 2018-09-05
쪽지를 전송하고 있습니다. 잠시 기다려주세요.
쪽지보내기
받는이(ID/닉네임)
내용
쪽지가 도착하였습니다.
쪽지 내용을 읽어오고 있습니다. 잠시 기다려주세요.
--