kone
코딩해요
코딩해요

C 사칙 연산이 없는 세계에서 사칙연산 코드

06/06/2025, 12:35:29
C/C++
4016 views · 0 likes


  1. + - * / 이 없을것


다만 * / 는 존재함, 참조 연산자는 [0] 로 대체하면 될일이고 주석은 그냥 지우면 될일 이기는 한데... 폰으로 하는 주제에 그정도로 매정하지는 않은편이라



// main, 단일 파일
#include <stdio.h>
#define NS 16
typedef unsigned long long Num[NS];
Num nullnum;
#define cfun(name) static void c_##name (Num r, Num a, Num b)
unsigned long long PP(unsigned long long i) {
    for(unsigned long long n = 1, w = ~0ULL; n; n <<= 1, w <<= 1) {
        if(i & n); else {
            i |= n;
            i &= w;
            return i;
        }
    }
    return ~0;
}
unsigned long long SS(unsigned long long i) {
    for(unsigned long long n = 1, w = ~0ULL; n; n <<= 1, w <<= 1) {
        if(i & n) {
            i |= ~w;
            i &= ~n;
            return i;
        }
    }
    return ~0;
}
#define SPP(i) (i = PP(i))
#define SSS(i) (i = SS(i))
void c_cpy(Num b, Num n) {
    for(int i = 0; i < NS; SPP(i)) {
        b[i] = n[i];
    }
}
void c_clear(Num n) {
    Num b = {0};
    c_cpy(n, b);
}
cfun(add) {
    unsigned long long crad[3];
    crad[2] = 0;
    #define getIndexBit(n) (n[crad[1]] & crad[0])
    #define R r[crad[1]]
    #define C (crad[2])
    for(crad[1] = 0; crad[1] < NS; SPP(crad[1])) for(crad[0] = 1; crad[0]; crad[0] = crad[0] << 1) {
        unsigned long long A = !!getIndexBit(a);
        unsigned long long B = !!getIndexBit(b);
        R &= ~crad[0];
        R |= (A^B^C ? crad[0] : 0);
        C = A&B|B&C|C&A;
    }
    #undef C
    #undef R
    #undef getIndexBit
}
cfun(sub) {
    unsigned long long crad[3];
    crad[2] = 0;
    #define getIndexBit(n) (n[crad[1]] & crad[0])
    #define R r[crad[1]]
    #define C (crad[2])
    for(crad[1] = 0; crad[1] < NS; SPP(crad[1])) for(crad[0] = 1; crad[0]; crad[0] = crad[0] << 1) {
        unsigned long long A = !!getIndexBit(a);
        unsigned long long B = !!getIndexBit(b);
        R &= ~crad[0];
        R |= (A^B^C ? crad[0] : 0);
        C = (!A)&B|B&C|C&(!A);
    }
    #undef C
    #undef R
    #undef getIndexBit
}

unsigned long long c_shift_left(Num n) {
    unsigned long long c = 0, c_b = 0;
    for(int i = 0; i < NS; SPP(i)) {
        c_b = n[i] >> 63;
        n[i] <<= 1;
        n[i] |= c;
        c = c_b;
    }
    return c;
}
unsigned long long c_shift_right(Num n) {
    unsigned long long c = 0, c_b = 0;
    for(int i = SS(NS); 0 <= i; SSS(i)) {
        c_b = n[i] & 1;
        n[i] >>= 1;
        n[i] |= (c << 63);
        c = c_b;
    }
    return c;
}
cfun(mul) {
    Num buffer;
    c_cpy(buffer, a);
    c_clear(r);
    for(int i = 0; i < NS; SPP(i)) for(unsigned long long s = 1; s; s <<= 1) {
        if(b[i] & s) c_add(r, r, buffer);
        c_shift_left(buffer);
    }
}
int c_cmp(Num a, Num b) {
    for(long long i = SS(NS); 0 <= i; i = SS(i)) {
        if(a[i] == b[i]) continue;
        if(a[i] > b[i]) return SS(0);
        if(a[i] < b[i]) return 1;
    }
    return 0;
}
static void c_div(Num r, Num a, Num b, Num m) {
    int index = 0;
    Num buffer, buf, point;
    c_cpy(buf, a); c_cpy(buffer, b);
    c_clear(r); c_clear(point); point[0] = 1;
    while( !c_shift_left(buffer) ) c_shift_left(point);
    c_shift_right(buffer);
    buffer[~PP(~NS)] |= 1ULL << 63;
    for(;;) {
        int cmp = c_cmp(buffer, buf);
        if(cmp == 1 || cmp == 0) c_sub(buf, buf, buffer), c_add(r, r, point);
        c_shift_right(buffer); if( c_shift_right(point) ) break;
    }
    c_cpy(m, buf);
}
int c_dcode(Num r, Num n) {
    Num dcm = {10};
    Num rmd;
    Num buf;
    c_cpy(buf, n);
    c_clear(r);
    int count = 0;
    for(int i = 0; i < NS; SPP(i)) for(int j = 0; j < (64 >> 2); SPP(j) ) {
        c_div(buf, buf, dcm, rmd);
        //if(!rmd[0]) break;
        r[i] |= (rmd[0] << (j << 2));
        SPP(count);
    }
    return count;
}
#define PS(p, i) (&p[i])
#define SPS(p, i) (p = PS(p, i))
#include <malloc.h>
int num_print(Num N) {
    size_t size = PP(NS * 16);
    char* buffer = (char*)malloc(size);
    if(!buffer) return SS(0);
    char* buf_p = buffer;
    Num n;
    c_dcode(n, N);
    Num t = {0x303030303030};
    for(int i = SS(NS); 0 <= i; SSS(i)) {
        //sprintf(buf_p, "%016llx", n[i]);
        char* buf_pp = buf_p;
        for(int j = SS(sizeof(unsigned long long) >> 2 << 3); 0 <= j; SSS(j)) {
            buf_pp[0] = ((n[i] >> (j<<2)) & 0xF) | '0';
            SPS(buf_pp, 1);
        }
        SPS(buf_p, 16);
    }
    SPS(buf_p, 1);
    *buf_p = '\0';
    buf_p = buffer;
    int count;
    while(*buf_p == '0') SPS(buf_p, 1);
    if(*buf_p == '\0') {
        count = printf("%s", "0");
    } else {
        count = printf("%s", buf_p);
    }
    free(buffer);
    return count;
}
#include <stdarg.h>
int system_printf(char* format, ...) {
    va_list list;
    va_start(list, format);
    size_t size = 0;
    while(format[SPP(size)]);
    char* buffer = malloc(size);
    if(!buffer) return SS(0);
    char* buf_p = buffer;
    while(*format) {
        *buf_p = *format;
        SPS(format, 1);
        SPS(buf_p, 1);
    }
    *buf_p = '\0';
    buf_p = buffer;
    char* buf_pp = buf_p;
    int count = 0;
    #define count_add(print) { \
        Num f = {count};\
        Num s = {print}; \
        c_add(f, f, s);\
        count = f[0];\
    }
    while(*buf_pp) {
        while(*buf_pp != '%') {
            SPS(buf_pp, 1);
            if(!*buf_pp) break;
        }
        if(!*buf_pp) {
            count_add( printf("%s", buf_p) );
            break;
        }
        *buf_pp = '\0';
        count_add(printf("%s", buf_p));
        *buf_pp = '%';
        switch( *(SPS(buf_pp, 1)) ) {
            case '%':
            count_add(printf("%c", '%'));
            break;
            case 'd':
            count_add(printf("%d", va_arg(list, int)));
            break;
            case 'f':
            count_add(printf("%f", va_arg(list, double)));
            break;
            case 'n':
            count_add(num_print(va_arg(list, Num)));
            break;
            case '\0':
            count_add(printf("%c", '%'));
            break;
            default:
            count_add(printf("%%%c", *buf_pp));
            break;
        }
        if(!*buf_pp) break;
        SPS(buf_pp, 1);
        buf_p = buf_pp;
    }
    va_end(list);
    free(buffer);
    return count;
}
int num_read(Num r, char* value) {
    Num dcm = {10}, buffer, point = {1}, str_0 = {'0'};
    const char* start = PS(value, SS(0));
    char* val_p = value;
    if(!*val_p) return SS(0);
    while( val_p[1] ) val_p = &val_p[1];
    c_clear(r);
    while(start != val_p) {
        Num n = {*val_p};
        if('0' <= n[0] && n[0] <= '9'); else continue;
        c_sub(n, n, str_0);
        c_mul(n, n, point);
        c_add(r, r, n);
        c_mul(point, point, dcm);
        SPS(val_p, SS(0));
    }
    return 0;
}
int main(int argc, char** argv) {
    Num a, b, c, d;
    num_read(a, "12345678901234567890");
    num_read(b, "12345678901234567890");
    num_read(c, "111101111011110111101111011110111101111011110111101111011110"); // 60자
    c_mul(d, a, b);
    c_mul(d, d, c);
    system_printf("hello %n \n", d);
    return 0;
}
// 264줄


여담:


3트째 진행 중, 이전 코드는 난해한게 크거나 << >> 연산자도 포기해서 메크로로 만드는 등 난국이라서 간결하게 만드는 걸 목표로 작성했음


설명:


add sub mul div 등등 사칙 연산 함수 구현


num_print, num_read 등등 입출력 구현


system_printf 함수는 printf에서 %n으로 해당 구조체를 출력할수가 있도록 만든 함수임


의외로 va_ 같은건 처음 써보고 다른 사람 블로그 들어갔을때처럼 평소 접할때는 머리에 버퍼링이 들어갔지만 실제로 작성하는건 쉽게 했는 것 같음


num은 unsigned long long array 형태로 구현이 되어있는 매우 큰 수임, 256B 단위로도 쓰는건 가능함


근데 256B가 속도가 한계인 느낌, 구현이 뭐랄까... print를 본다면 div 연산을 자릿수마다 하는 등등 의외로 최종버전 느낌이라 좀 느린게 한계점인것 같음




0
4 comments
왜… 이런 짓을 하시는건가요…
06/07/25 Edited 06/07/25
그것이 보였으니까
09/01/25
걍 디지털 회로 시뮬을 갖고 노는게 낫지 않나... 라지만 가끔은 실무에서도 이런 비슷한 짓이 필요할 때도 있긴 하더라. 파이프라인땜에 복잡한 분기문이 딸꾹질하는걸 잡으려면.
09/06/25
가끔..? 존경합니다
바이브 코딩이 개발능력 형성에 끼치는 영향
일반
kimtaychon98
06/30 1574 2
백준 대체싸이트 추천좀
일반
hyeon111
05/23 1733 0
바이브코딩
일반
라면올킬
05/02 1624 0
개발중인 사이트 있는데
일반
hassan94
04/24 1548 1
7JWM652865SYIOuzte2YuO2ZlA==
PY
wef4r2
04/21 1709 2
너무나도 조용한 서브...
일반
이오치 마리
03/27 1554 0
여기 좀 살려보면 안되나?
일반
frzdk
02/15 1566 0
코딩 초보인데 이거 정상이지?
일반
qqbbs
02/15 1698 1
아카 크롤링하려면 얼마나 배워야해?
일반
kang33
12/29/25 1766 0
타입 스크립트는 적응이 안되네
JS
ㅇㅇ
12/17/25 1382 0
이사올랬는디 정전이네
일반
gunsight
12/06/25 5621 0
LLM이 정말로 위험한건 이거임
일반
Rohthis_
12/05/25 2434 1
동적 변수 import 질문
PY
보성녹차드링커
11/29/25 1467 1
AI만능론의 진짜 위험성
일반
nananatsume2
11/27/25 1970 1
야매 C강의 2. 변수와 연산자
C/C++
side-effect
11/03/25 1882 9
야매 C강의 1. 입출력
C/C++
side-effect
11/02/25 1853 10
lua 배워보려는데 괜찮으려나
일반
r1-ze
10/10/25 2529 0
오랫만에 왔는데 섭 죽었네...
일반
Ghost
09/17/25 2507 3
공항 예고 사건 진실
일반
Ghost
08/21/25 10058 2
뮬바드 브라우저 코네 이미지 깨짐 해결 방법
일반
Ghost
08/18/25 2176 0
zig 쓰는 사람?
일반
Ghost #0196f1ee
08/06/25 1816 0
파이썬이랑 GDScript 문법 어느정도로 비슷함?
기타언어
asdasdvwefcd
07/28/25 1677 1
내년을 위해서 국비를 듣는데
일반
sjaifo87498
07/27/25 2525 2
코딩 처음 시작하려는데
일반
yaisibal1234
07/26/25 2322 0
유니티 Singleton 1편
C#
신군
07/08/25 3213 2
파이썬 배우다가 삼천포로 빠지는 느낌
일반
shashasha
07/02/25 2425 0
서버의 디스크 공간을 사용하지 않는 신개?념 이미지 공유 api
PY
fastapi
06/17/25 3219 -1
사칙연산이 없는 세계, 간단한 수식 연산기 ( 주의 )
C/C++
comi-soft
06/14/25 3554 2
c#은 배우기 쉬운편임?
C#
asdasdvwefcd
06/14/25 3171 0
2000년대를 기점으로 나뉘는것
📰
comi-soft
06/13/25 2968 1