From fb4c6efd9206f3c51f05cfc088b18aaf84cf888b Mon Sep 17 00:00:00 2001 From: anttoinettae <80488485+anttoinettae@users.noreply.github.com> Date: Sat, 23 Oct 2021 16:58:21 +0300 Subject: [PATCH 1/2] Add files via upload --- unit1024.c | 199 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 199 insertions(+) create mode 100644 unit1024.c diff --git a/unit1024.c b/unit1024.c new file mode 100644 index 0000000..117bd6d --- /dev/null +++ b/unit1024.c @@ -0,0 +1,199 @@ +#include +#include +#include + +const uint32_t mask32 = 0x0000ffff; + +typedef struct uint1024_t { + uint32_t r0; + uint32_t r1; + uint32_t r2; + uint32_t r3; + uint32_t r4; + uint32_t r5; + uint32_t r6; + uint32_t r7; + uint32_t r8; + uint32_t r9; + uint32_t r10; + uint32_t r11; + uint32_t r12; + uint32_t r13; + uint32_t r14; + uint32_t r15; + uint32_t r16; + uint32_t r17; + uint32_t r18; + uint32_t r19; + uint32_t r20; + uint32_t r21; + uint32_t r22; + uint32_t r23; + uint32_t r24; + uint32_t r25; + uint32_t r26; + uint32_t r27; + uint32_t r28; + uint32_t r29; + uint32_t r30; + uint32_t r31; + uint32_t error; +}uint1024_t; + + +uint1024_t from_uint(unsigned int x){ + uint1024_t r; + r.error = 0; + + for (uint8_t i = 0; i < 32; i++) //делаем число не мусором + *(&r.r0 + i) = 0x00000000; + + r.r0 = x; + + return r; +} + + +uint32_t add_segment(uint32_t x, uint32_t y, uint32_t d, uint32_t* r) { + uint64_t t = x + y + d; + *r = t & mask32; + return t >> 32; // происходит обрезание +} + +uint1024_t add_op(uint1024_t x, uint1024_t y) { + uint1024_t r = from_uint(0); + + if (x.error > 0 || y.error > 0) { + r.error = 1; + return r; + } + + uint32_t d = 0; // переполнение лежит тут + for (uint8_t i = 0; i < 32; i++){ + d = add_segment(*(&x.r0 + i), *(&y.r0 + i), d, &r.r0 + i); //звездочкой выковыриваем значение + } + if (d > 0) // если переполнение все еще есть оно слишом переполнилось + r.error = 1; + + return r; +} + +uint32_t subtr_segment(uint32_t x, uint32_t y, uint32_t d, uint32_t* r) { + uint64_t t = 0; + if (x < y + d) { + t = 1; + x += 0x00010000; // заняли разряд + } + *r = x - y - d; + return t; +} + +uint1024_t subtr_op(uint1024_t x, uint1024_t y) { + uint1024_t r = from_uint(0); + + if (x.error > 0 || y.error > 0) { + r.error = 1; + return r; + } + + uint32_t d = 0; // тут занимание + for (uint8_t i = 0; i < 32; i++) + d = subtr_segment(*(&x.r0 + i), *(&y.r0 + i), d, &r.r0 + i); + + if (d > 0) // переполнилось занимание + r.error = 1; + + return r; +} + +uint32_t mult_segment(uint32_t x, uint32_t y, uint32_t d, uint32_t* r) { + uint64_t t = x * y + d; + *r += t & mask32; + return t >> 32; +} + +uint1024_t mult_op(uint1024_t x, uint1024_t y) +{ + uint1024_t r = from_uint(0); + + if (x.error > 0 || y.error > 0) { + r.error = 1; + return r; + } + + + uint32_t d = 0; + for (uint8_t j = 0; j < 32; j++) + for (uint8_t i = 0; i < 32-j; i++) { + d = mult_segment(*(&x.r0 + i), *(&y.r0 + j), d, &r.r0 + (j+i)); + if (i+j == 31 && d > 0) { + r.error = 1; + return r; + } + } + + return r; +} +void printf_value(uint1024_t x) { + for (uint8_t i = 0; i < 32; i++){ + printf("%d", *(&x.r31 - i)); + } +} +void scanf_value(uint1024_t* x){ + + uint1024_t r = from_uint(0); + + char str[4000]; + gets(str); + + uint1024_t base = from_uint(1); + uint1024_t ten = from_uint(10); + + + for (int i = strlen(str) - 1; i >= 0; i--){ + int a = str[i] - 48; + uint1024_t anew = from_uint(a); + uint1024_t temp = mult_op(anew, base); + r = add_op(r, temp); + base = mult_op(base, ten); + } + *x = r; +} + + +int main() { + char a; + uint1024_t x, y; + printf("Enter first number: \n"); + scanf_value(&x); + printf("Enter second number: \n"); + scanf_value(&y); + printf("Enter action you would like to use: (+, -, *) \n"); + scanf("%s", &a); + if (a == '+') { + printf("Answer: "); + if (add_op(x, y).error == 1){ + printf("%s", "переполнение"); + } else { + printf_value(add_op(x, y)); + } + } else if (a == '-') { + printf("Answer: "); + if (subtr_op(x, y).error == 1){ + printf("%s", "переполнение"); + } else { + printf_value(subtr_op(x, y)); + } + } else if (a == '*') { + printf("Answer: "); + if (mult_op(x, y).error == 1){ + printf("%s", "переполнение"); + } else { + printf_value(mult_op(x, y)); + } + + } + + return 0; +} + From dd20d1a9e40f23b221ad76d6b6039ba9481274d1 Mon Sep 17 00:00:00 2001 From: anttoinettae <80488485+anttoinettae@users.noreply.github.com> Date: Sat, 15 Jan 2022 15:44:46 +0300 Subject: [PATCH 2/2] =?UTF-8?q?=D1=8F=20=D1=81=D0=B4=D0=B5=D0=BB=D0=B0?= =?UTF-8?q?=D0=BB=D0=B0=20=D0=B2=D1=82=D0=BE=D1=80=D1=83=D1=8E!!!!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- unit1024.c | 384 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 243 insertions(+), 141 deletions(-) diff --git a/unit1024.c b/unit1024.c index 117bd6d..57f3ea9 100644 --- a/unit1024.c +++ b/unit1024.c @@ -1,199 +1,301 @@ #include #include #include +#include -const uint32_t mask32 = 0x0000ffff; - -typedef struct uint1024_t { - uint32_t r0; - uint32_t r1; - uint32_t r2; - uint32_t r3; - uint32_t r4; - uint32_t r5; - uint32_t r6; - uint32_t r7; - uint32_t r8; - uint32_t r9; - uint32_t r10; - uint32_t r11; - uint32_t r12; - uint32_t r13; - uint32_t r14; - uint32_t r15; - uint32_t r16; - uint32_t r17; - uint32_t r18; - uint32_t r19; - uint32_t r20; - uint32_t r21; - uint32_t r22; - uint32_t r23; - uint32_t r24; - uint32_t r25; - uint32_t r26; - uint32_t r27; - uint32_t r28; - uint32_t r29; - uint32_t r30; - uint32_t r31; - uint32_t error; -}uint1024_t; - - -uint1024_t from_uint(unsigned int x){ - uint1024_t r; - r.error = 0; - - for (uint8_t i = 0; i < 32; i++) //делаем число не мусором - *(&r.r0 + i) = 0x00000000; +const uint32_t MASK832 = 0x000000ff; +const uint32_t MASK816 = 0x00ff; +const uint16_t DECLENGTH = 3277; // HEXLENGTH * 256 / 10 = кол-во десятичных разрядов числа +const uint8_t HEXLENGTH = 128; // uint8_t == 2**8; 1024 / 8 = HEXLENGTH - r.r0 = x; +typedef uint8_t uint1024_t[128]; - return r; +void initu(uint1024_t r) { + memset(r, 0, HEXLENGTH); //делаем число не мусором } +void initc(char *r) { + memset(r, '\0', DECLENGTH); //делаем число не мусором +} -uint32_t add_segment(uint32_t x, uint32_t y, uint32_t d, uint32_t* r) { - uint64_t t = x + y + d; - *r = t & mask32; - return t >> 32; // происходит обрезание +bool from_uint(unsigned int x, uint1024_t r) { + // unsigned int === uint32_t + initu(r); + for (int i = 0; i < 4; i++) { + r[i] = x & MASK832; + x >>= 8; + } + return true; } -uint1024_t add_op(uint1024_t x, uint1024_t y) { - uint1024_t r = from_uint(0); +void copy(uint1024_t src, uint1024_t dst) { + initu(dst); + memcpy(dst, src, HEXLENGTH); +} - if (x.error > 0 || y.error > 0) { - r.error = 1; - return r; +bool is_zero_op(uint1024_t x) { + for (int i = 0; i < HEXLENGTH; i++){ + if (x[i]){ + return false; + } } + return true; +} - uint32_t d = 0; // переполнение лежит тут - for (uint8_t i = 0; i < 32; i++){ - d = add_segment(*(&x.r0 + i), *(&y.r0 + i), d, &r.r0 + i); //звездочкой выковыриваем значение - } - if (d > 0) // если переполнение все еще есть оно слишом переполнилось - r.error = 1; +uint8_t add_rank(uint8_t x, uint8_t y, uint8_t d, uint8_t *r) { + uint16_t t = x; + t += y; + t += d; + *r = (uint8_t)(t & MASK816); + return (uint8_t)(t >> 8); // происходит обрезание +} + +bool add_op(uint1024_t x, uint1024_t y, uint1024_t r) { + uint8_t d = 0; // переполнение лежит тут - return r; + initu(r); + for (int i = 0; i < HEXLENGTH; i++) + d = add_rank(x[i], y[i], d, r+i); + return d == 0; // самого старшего переполнения быть не должно } -uint32_t subtr_segment(uint32_t x, uint32_t y, uint32_t d, uint32_t* r) { - uint64_t t = 0; +uint8_t subtr_rank(uint8_t x, uint8_t y, uint8_t d, uint8_t *r) { + uint16_t t = x; + uint8_t dd = 0; + if (x < y + d) { - t = 1; - x += 0x00010000; // заняли разряд + t += 0x0100; // заняли разряд + dd = 1; } - *r = x - y - d; - return t; + t -= y; + t -= d; + *r = (uint8_t)t; + return dd; } -uint1024_t subtr_op(uint1024_t x, uint1024_t y) { - uint1024_t r = from_uint(0); +bool subtr_op(uint1024_t x, uint1024_t y, uint1024_t r) { + uint8_t d = 0; // тут занимание - if (x.error > 0 || y.error > 0) { - r.error = 1; - return r; - } + initu(r); + for (int i = 0; i < HEXLENGTH; i++) + d = subtr_rank(x[i], y[i], d, r+i); + return d == 0; // самого старшего занимания быть не должно +} - uint32_t d = 0; // тут занимание - for (uint8_t i = 0; i < 32; i++) - d = subtr_segment(*(&x.r0 + i), *(&y.r0 + i), d, &r.r0 + i); +bool mult_rank(uint8_t x, uint8_t y, uint1024_t r, int i) { + uint32_t t = x * y; + uint16_t d = 0; + + if (i >= HEXLENGTH) + return false; + for (int j = i; j < HEXLENGTH; j++) { + t += d + (r[j] & MASK832); + r[j] = (uint8_t)(t & MASK832); + d = (uint16_t)(t >> 8); + if (j == HEXLENGTH-1 && d){ + return false; // самого старшего переполнения быть не должно + } + if (!d){ + break; // всплывание переполнения закончилось + } + t = 0; + } + return true; +} - if (d > 0) // переполнилось занимание - r.error = 1; +bool mult_op8(uint1024_t x, uint8_t y, uint1024_t r) { + initu(r); + for (int i = 0; i < HEXLENGTH; i++) { + if (x[i] && y) { + if (!mult_rank(x[i], y, r, i)) + return false; + } + } + return true; +} - return r; +bool mult_op(uint1024_t x, uint1024_t y, uint1024_t r) { + initu(r); + for (int j = 0; j < HEXLENGTH; j++) { + for (int i = 0; i < HEXLENGTH; i++) { + if (x[i] && y[j]) { + if (i+j < HEXLENGTH) { + if (!mult_rank(x[i], y[j], r, i+j)) + return false; + } + } + } + } + return true; } -uint32_t mult_segment(uint32_t x, uint32_t y, uint32_t d, uint32_t* r) { - uint64_t t = x * y + d; - *r += t & mask32; - return t >> 32; +int compare_op(uint1024_t x, uint1024_t y) { + for (int i = HEXLENGTH-1; i >= 0; i--) { + if (x[i] > y[i]) + return 1; + else if (x[i] < y[i]) + return -1; + } + return 0; } -uint1024_t mult_op(uint1024_t x, uint1024_t y) -{ - uint1024_t r = from_uint(0); +bool scanf_value(uint1024_t r) { + char str[DECLENGTH]; + uint1024_t dec10; // число текущей степени 10 + uint32_t a; + uint1024_t tmp; + uint1024_t anew; - if (x.error > 0 || y.error > 0) { - r.error = 1; - return r; + initu(r); + from_uint(1, dec10); + + gets(str); + for (int i = (int)strlen(str)-1; i >= 0; i--) { + a = str[i] - 48; + from_uint(a, anew); + + // умножаем anew на dec10 + if (!mult_op(dec10, anew, tmp)) + return false; + copy(tmp, anew); + + // прибавляем anew к r + if (!add_op(anew, r, tmp)) + return false; + copy(tmp, r); + + // умножаем dec10 на 10 кроме последнего разряда + if (i > 0) { + if (!mult_op8(dec10, 10, tmp)) + return false; + copy(tmp, dec10); + } } + return true; +} +bool printf_value_hex(uint1024_t x) { - uint32_t d = 0; - for (uint8_t j = 0; j < 32; j++) - for (uint8_t i = 0; i < 32-j; i++) { - d = mult_segment(*(&x.r0 + i), *(&y.r0 + j), d, &r.r0 + (j+i)); - if (i+j == 31 && d > 0) { - r.error = 1; - return r; - } + bool isleading = true; + for (int i = 127; i >= 0; i--) { + if (x[i] > 0 || !isleading) { + if (isleading) + printf("0x%X", x[i] & 0xff); + else + printf("%02X", x[i] & 0xff); + isleading = false; } - - return r; -} -void printf_value(uint1024_t x) { - for (uint8_t i = 0; i < 32; i++){ - printf("%d", *(&x.r31 - i)); } + printf("\n"); + return true; } -void scanf_value(uint1024_t* x){ - uint1024_t r = from_uint(0); +bool printf_value(uint1024_t x) { - char str[4000]; - gets(str); + char dec[DECLENGTH]; + uint1024_t y; // копия входного числа (будет модифицирована) + uint1024_t dec10; // число текущей степени 10 + uint1024_t tmp, tmp1 ; // промежуточные для вычислений + int rank; // текущий десятичный разряда + uint8_t n; // значение текущего десятичного разряда - uint1024_t base = from_uint(1); - uint1024_t ten = from_uint(10); + copy(x, y); + initc(dec); // инициализация нулями + from_uint(1, tmp); + // находим максимальную степень 10 (dec10) меньшую исходного числа + for (rank = 0; compare_op(y, tmp) != -1; rank++) { + if (!mult_op8(tmp, 10, tmp1)) + return false; + copy(tmp1, tmp); + } - for (int i = strlen(str) - 1; i >= 0; i--){ - int a = str[i] - 48; - uint1024_t anew = from_uint(a); - uint1024_t temp = mult_op(anew, base); - r = add_op(r, temp); - base = mult_op(base, ten); + for (uint8_t i = 0; i < DECLENGTH; i++, rank--) { + if (is_zero_op(y)) { + if (rank > 0) { + dec[i] = 48; // завершающие нули + continue; + } else { + break; + } + } + from_uint(1, dec10); + for (uint8_t j = 0; j < rank-1; j++) { + if (!mult_op8(dec10, 10, tmp)) + return false; + copy(tmp, dec10); + } + // на данный момент в dec10 лежит на разряд меньше dectmp = 1 * 10 ** i + copy(dec10, tmp); + copy(dec10, tmp1); + for (n = 0; compare_op(y, tmp) != -1; n++) { + copy(tmp, dec10); + if (!add_op(dec10, tmp1, tmp)) + return false; + } + dec[i] = n + 48; // сохраняем значение разряда как символ цифры + if (!n) + continue; + // на данный момент в dec10 лежит n * 10 ** i + // вычитаем из y найденное десятичное число + if (subtr_op(y, dec10, tmp)) { + copy(tmp, y); // если получилось, переходим к более младшему разряду + } else { + dec[i+1] = n + 48; // остался остаток от деления на 10 == младшая десятичная цифра + break; + } } - *x = r; + printf("%s\n", dec); + return true; } - int main() { char a; - uint1024_t x, y; - printf("Enter first number: \n"); - scanf_value(&x); - printf("Enter second number: \n"); - scanf_value(&y); - printf("Enter action you would like to use: (+, -, *) \n"); + uint1024_t x; + uint1024_t y; + uint1024_t r; + + printf("Enter first number:\n"); + if (!scanf_value(x)) + printf("scanf_value failed\n"); + printf("Entered x="); + if (!printf_value(x)) + return false; + printf("\n"); + printf("Enter second number:\n"); + if (!scanf_value(y)) + printf("scanf_value failed\n"); + printf("Entered y="); + if (!printf_value(y)) + return false; + printf("\n"); + printf("Enter operation you would like to perform: (+, -, *)\n"); scanf("%s", &a); + printf("Chosen operation %c\n", a); if (a == '+') { printf("Answer: "); - if (add_op(x, y).error == 1){ - printf("%s", "переполнение"); - } else { - printf_value(add_op(x, y)); - } + if (add_op(x, y, r)) + printf_value(r); + else + printf("переполнение"); + printf("\n"); } else if (a == '-') { printf("Answer: "); - if (subtr_op(x, y).error == 1){ - printf("%s", "переполнение"); - } else { - printf_value(subtr_op(x, y)); + if (subtr_op(x, y, r)) + printf_value(r); + else { + printf("переполнение"); } + printf("\n"); } else if (a == '*') { printf("Answer: "); - if (mult_op(x, y).error == 1){ - printf("%s", "переполнение"); - } else { - printf_value(mult_op(x, y)); + if (mult_op(x, y, r)) + printf_value(r); + else { + printf("переполнение"); } - + printf("\n"); } return 0; -} - +} \ No newline at end of file