├── calc ├── test ├── calc2 ├── calc.h ├── README.md ├── utils.h ├── Makefile ├── calc2.c ├── test.c ├── util.h ├── calc.c ├── utils.c └── util.c /calc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/i/calc/master/calc -------------------------------------------------------------------------------- /test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/i/calc/master/test -------------------------------------------------------------------------------- /calc2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/i/calc/master/calc2 -------------------------------------------------------------------------------- /calc.h: -------------------------------------------------------------------------------- 1 | #ifndef CALC_H 2 | #define CALC_H 3 | 4 | 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | calc (School project) 2 | ==== 3 | 4 | Base conversion, binary arithmetic, floating point representation. Can compute arbitrarily long numbers. 5 | -------------------------------------------------------------------------------- /utils.h: -------------------------------------------------------------------------------- 1 | #ifndef UTIL_H 2 | #define UTIL_H 3 | 4 | int getbase(char *); 5 | int getdec(char); 6 | char fromdec(int); 7 | int lmfao(char *); 8 | char * build(int, char); 9 | 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | <<<<<<< HEAD 2 | FILES=utils.c calc2.c 3 | CFLAGS=-lm -ansi -pedantic -Wall -Werror 4 | ======= 5 | FILES=util.c calc.c 6 | CFLAGS=-lm -ansi -pedantic -Wall 7 | >>>>>>> 886fe1de95e168a9ff79fa2837f6f1c485808863 8 | 9 | all: 10 | gcc $(FILES) $(CFLAGS) -o calc 11 | 12 | debug: 13 | gcc $(FILES) $(CFLAGS) -g -o calc 14 | 15 | clean: 16 | rm calc 17 | -------------------------------------------------------------------------------- /calc2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "utils.h" 6 | 7 | int main(int argc, char ** argv){ 8 | int num1, num2, ans; 9 | char * ret; 10 | 11 | if(argc != 5){ 12 | fprintf(stderr, "ERROR wrong number args\n"); 13 | exit(1); 14 | } 15 | 16 | num1 = lmfao(argv[2]); 17 | num2 = lmfao(argv[3]); 18 | 19 | if(argv[1][0] == '+') ans = num1 + num2; 20 | if(argv[1][0] == '-') ans = num1 - num2; 21 | 22 | ret = build(ans, argv[4][0]); 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "util.h" 7 | 8 | int main(int argc, char ** argv){ 9 | char * num1, * sum, hex, *nibble, *sub; 10 | 11 | num1 = argv[1]; 12 | sub = substr(num1, 1, 5); 13 | printf("sub: %s\n", sub); 14 | 15 | /* hex = nib_to_hex(num1);*/ 16 | /* printf("hex: %c\n",hex);*/ 17 | /**/ 18 | /* nibble = hex_to_nib(hex);*/ 19 | /* printf("%s\n",nibble);*/ 20 | /**/ 21 | /* num1 = malloc(strlen(nibble)+1);*/ 22 | /* strcpy(num1,nibble);*/ 23 | /* num1 = twos_comp(nibble);*/ 24 | /* printf("%s\n", num1);*/ 25 | /**/ 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /util.h: -------------------------------------------------------------------------------- 1 | #ifndef UTIL_H 2 | #define UTIL_H 3 | 4 | char * to_bin(char *); 5 | char * from_bin(char *, char); 6 | 7 | char * add(char *, char *); 8 | char * subtract(char *, char *); 9 | char * multiply(char *, char *); 10 | 11 | int addDigit(char, char, int); 12 | int max(int, int); 13 | int min(int, int); 14 | 15 | char * cat(char *, char *); 16 | char * minstr(char *, char *); 17 | char * substr(char *, int, int); 18 | char * maxstr(char *, char *); 19 | 20 | 21 | char * decbits(char); 22 | void flip_bits(char *); 23 | char * twos_comp(char *); 24 | void strrev(char *); 25 | 26 | char nib_to_hex(char *); 27 | char * hex_to_nib(char); 28 | 29 | 30 | /*todo*/ 31 | /*binary to decimal*/ 32 | /*binary to octal*/ 33 | /*binary to hex*/ 34 | 35 | /*octal to binary*/ 36 | /*octal to binary*/ 37 | /*hex to binary*/ 38 | 39 | /*subtraction*/ 40 | /*negatives*/ 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /calc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "util.h" 6 | 7 | /*input should be ./calc */ 8 | int main(int argc, char ** argv){ 9 | char * bin1, * bin2, * binanswer, * ret, op, retbase; 10 | 11 | if(argc != 5){ 12 | fprintf(stderr, "ERROR wrong number of arguments\n"); 13 | exit(1); 14 | } 15 | 16 | op = argv[1][0]; 17 | retbase = argv[4][0]; 18 | 19 | bin1 = to_bin(argv[2]); 20 | bin2 = to_bin(argv[3]); 21 | 22 | switch(op){ 23 | case '+': 24 | binanswer = add(bin1, bin2); 25 | break; 26 | 27 | case '-': 28 | binanswer = subtract(bin1, bin2); 29 | break; 30 | 31 | case '*': 32 | /* //things*/ 33 | break; 34 | 35 | default: 36 | fprintf(stderr, "ERROR invalid operator"); 37 | free(bin1); 38 | free(bin2); 39 | exit(1); 40 | } 41 | 42 | ret = from_bin(binanswer, retbase); 43 | printf("%c%s\n", retbase, ret); 44 | 45 | free(bin1); 46 | free(bin2); 47 | free(binanswer); 48 | free(ret); 49 | 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /utils.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | 6 | int getbase(char * b){ 7 | printf("getbase -- base: %c\n", b[0]); 8 | switch (b[0]){ 9 | case 'd': 10 | case 'D': 11 | return 10; 12 | case 'x': 13 | case 'X': 14 | case 'h': 15 | case 'H': 16 | return 16; 17 | case 'b': 18 | case 'B': 19 | return 2; 20 | case 'o': 21 | case 'O': 22 | return 8; 23 | default: 24 | fprintf(stderr, "ERROR invalid base\n"); 25 | exit(1); 26 | } 27 | } 28 | 29 | 30 | 31 | int getdec(char d){ 32 | switch (d){ 33 | case '0': 34 | return 0; 35 | case '1': 36 | return 1; 37 | case '2': 38 | return 2; 39 | case '3': 40 | return 3; 41 | case '4': 42 | return 4; 43 | case '5': 44 | return 5; 45 | case '6': 46 | return 6; 47 | case '7': 48 | return 7; 49 | case '8': 50 | return 8; 51 | case '9': 52 | return 9; 53 | case 'A': 54 | case 'a': 55 | return 10; 56 | case 'B': 57 | case 'b': 58 | return 11; 59 | case 'C': 60 | case 'c': 61 | return 12; 62 | case 'D': 63 | case 'd': 64 | return 13; 65 | case 'E': 66 | case 'e': 67 | return 14; 68 | case 'F': 69 | case 'f': 70 | return 15; 71 | default: 72 | fprintf(stderr, "ERROR NOT A VALID CHARACTER!!!!!"); 73 | exit(1); 74 | } 75 | return 0; 76 | } 77 | 78 | char fromdec(int d){ 79 | switch(d){ 80 | case 1: 81 | return '1'; 82 | case 2: 83 | return '2'; 84 | case 3: 85 | return '3'; 86 | case 4: 87 | return '4'; 88 | case 5: 89 | return '5'; 90 | case 6: 91 | return '6'; 92 | case 7: 93 | return '7'; 94 | case 8: 95 | return '8'; 96 | case 9: 97 | return '9'; 98 | case 10: 99 | return 'A'; 100 | case 11: 101 | return 'B'; 102 | case 12: 103 | return 'C'; 104 | case 13: 105 | return 'D'; 106 | case 14: 107 | return 'E'; 108 | case 15: 109 | return 'F'; 110 | default: 111 | fprintf(stderr, "ERROR OH GOD SOMETHING BAD HAPPENTT!!!11"); 112 | exit(1); 113 | } 114 | } 115 | 116 | int lmfao(char * s){ 117 | int ret, base; 118 | 119 | base = getbase(s); 120 | ret = 0; 121 | s++; 122 | while(*s != '\0'){ 123 | ret *= base; 124 | ret += getdec(*s); 125 | s++; 126 | } 127 | return ret; 128 | } 129 | 130 | char * build(int num, char base){ 131 | char * ret; 132 | 133 | while(num > 1){ 134 | 135 | 136 | return ret; 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /util.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "util.h" 7 | 8 | char * to_bin(char * s){ 9 | int negative, num, i; 10 | char base, * ret, * bits; 11 | 12 | if(s[0] == '-') { 13 | negative = 1; 14 | base = s[1]; 15 | } 16 | else{ base = s[0]; } 17 | 18 | if(negative){ 19 | negative = 1; /* handle negative values*/ 20 | } 21 | 22 | switch(base){ 23 | case 'b': 24 | case 'B': 25 | ret = malloc(sizeof(strpbrk(s, "10"))); 26 | strcpy(ret, strpbrk(s, "10")); 27 | return ret; 28 | break; 29 | 30 | case 'o': 31 | case 'O': 32 | /* do a thing*/ 33 | break; 34 | 35 | case 'd': 36 | case 'D': 37 | ret = malloc(1000); 38 | ret = "0"; 39 | for(i=0; i < strlen(s); i++){ 40 | bits = decbits(s[strlen(s)-i-1]); 41 | printf("%s\n",bits); 42 | strcat(ret, bits); 43 | free(bits); 44 | } 45 | 46 | 47 | /* do more things*/ 48 | break; 49 | 50 | case 'x': 51 | case 'X': 52 | case 'h': 53 | case 'H': 54 | /* do things*/ 55 | break; 56 | 57 | default: 58 | fprintf(stderr, "ERROR Invalid operand\n"); 59 | exit(1); 60 | } 61 | return 0; 62 | } 63 | 64 | /*converts binary number to (o)octal, (h)hexadecimal, (d)decimal*/ 65 | char * from_bin(char * bin, char base){ 66 | int i, len; 67 | long num = 0; 68 | char digit, * ret, nibble[4]; 69 | 70 | switch (base){ 71 | case 'b': 72 | case 'B': 73 | ret = malloc(strlen(bin)+1); 74 | strcpy(ret,strpbrk(bin, "1")); 75 | return ret; 76 | 77 | case 'o': 78 | case 'O': 79 | /* binary to octal conversion*/ 80 | break; 81 | 82 | case 'h': 83 | case 'H': 84 | case 'x': 85 | case 'X': 86 | for(i = 0; i < strlen(bin); i++){ 87 | /* grab four bytes*/ 88 | 89 | 90 | 91 | } 92 | break; 93 | 94 | case 'd': 95 | for(i = 0; i < strlen(bin); i++){ 96 | if(bin[i] == '1'){ 97 | num += pow(2, strlen(bin)-i-1); 98 | } 99 | else if(bin[i] == '0'){continue;} 100 | else{ 101 | fprintf(stderr, "Backend error: tried to convert nonbinary number as binary"); 102 | exit(1); 103 | } 104 | } 105 | 106 | len = (int)log10(num)+1; 107 | ret = malloc(len); 108 | 109 | for(i = 0; i < len; i++){ 110 | digit = (int) num % 10 + '0'; 111 | ret[i] = digit; 112 | num /= 10; 113 | } 114 | 115 | strrev(ret); 116 | return ret; 117 | break; 118 | 119 | default: 120 | fprintf(stderr, "ERROR invalid base for output!\n"); 121 | exit(1); 122 | } 123 | return 0; 124 | } 125 | 126 | 127 | char * add(char * num1, char * num2){ 128 | char * ret, * s, * big, * small; 129 | int i, carry; 130 | 131 | if(strlen(num1) > strlen(num2)){ 132 | big = num1; 133 | small = num2; 134 | } else { 135 | big = num2; 136 | small = num1; 137 | } 138 | 139 | s = malloc(strlen(big)); 140 | for(i = 0; i < strlen(big)-strlen(small); i++) {strcat(s,"0");} 141 | strcat(s, small); 142 | 143 | carry = 0; 144 | ret = cat("0", big); 145 | 146 | for(i = 0; i < strlen(big); i++){ 147 | 148 | switch ( addDigit(ret[strlen(ret)-i-1], s[strlen(s)-i-1], carry) ){ 149 | 150 | case 0: 151 | ret[strlen(ret)-i-1] = '0'; 152 | carry = 0; 153 | break; 154 | 155 | case 1: 156 | ret[strlen(ret)-i-1] = '1'; 157 | carry = 0; 158 | break; 159 | 160 | case 2: 161 | ret[strlen(ret)-i-1] = '0'; 162 | carry = 1; 163 | break; 164 | 165 | case 3: 166 | ret[strlen(ret)-i-1] = '1'; 167 | carry = 1; 168 | break; 169 | 170 | default: 171 | fprintf(stderr, "ERROR something went wrong!\n"); 172 | exit(1); 173 | } 174 | } 175 | if(carry){ 176 | ret[0] = '1'; 177 | } 178 | free(s); 179 | return ret; 180 | } 181 | 182 | /*subtracts bin2 from bin1*/ 183 | char * subtract(char * minuend, char * subtrahend){ 184 | char * diff, * temp; 185 | 186 | printf("adding: %s to %s\n",minuend, twos_comp(subtrahend)); 187 | temp = add(minuend, twos_comp(subtrahend)); 188 | /* diff = malloc(strlen(strpbrk(++temp, "01")) + 1);*/ 189 | /* strcpy(diff, strpbrk(++temp, "10"));*/ 190 | diff = malloc(strlen(temp) + 1); 191 | strcpy(diff, temp); 192 | if(diff[0] == '\0'){ 193 | diff = "0"; 194 | } 195 | 196 | return diff; 197 | } 198 | 199 | /*char * multiply(char * multiplicitand1, char * multiplix0r){*/ 200 | /* char * sum;*/ 201 | /* int i, multiplizagsxfr;*/ 202 | /* multiplizagsxfr = 0;*/ 203 | /*}*/ 204 | 205 | 206 | int addDigit(char d1, char d2, int carry){ 207 | return (d1 - '0') + (d2 - '0') + carry; 208 | } 209 | 210 | 211 | char * cat(char * s1, char * s2){ 212 | char * ret; 213 | ret = malloc(strlen(s1) + strlen(s2) + 1); 214 | strcpy(ret,s1); 215 | strcat(ret,s2); 216 | return ret; 217 | } 218 | 219 | 220 | int max(int num1,int num2){ 221 | if(num1 >= num2) 222 | return num1; 223 | return num2; 224 | } 225 | 226 | int min(int num1, int num2){ 227 | if(num1 < num2) 228 | return num1; 229 | return num2; 230 | } 231 | 232 | /*returns the shorter of two strings*/ 233 | char * shorter(char * s1, char * s2){ 234 | if(strlen(s1) <= strlen(s2)) 235 | return s1; 236 | return s2; 237 | } 238 | 239 | void strrev(char * s){ 240 | char * e, t; 241 | e = s + strlen(s) - 1; 242 | while(s < e){ 243 | t = *s; 244 | *s = *e; 245 | *e = t; 246 | e--; s++; 247 | return; 248 | } 249 | } 250 | 251 | void flip_bits(char * bits){ 252 | while (*bits != '\0'){ 253 | if(*bits == '0') {*bits = '1';} 254 | else if(*bits == '1') {*bits = '0';} 255 | else{ 256 | fprintf(stderr, "ERROR"); 257 | exit(1); 258 | } 259 | bits++; 260 | } 261 | } 262 | 263 | char * twos_comp(char * bits){ 264 | char * ret; 265 | flip_bits(bits); 266 | ret = add(bits, "1"); 267 | return ret; 268 | } 269 | 270 | char nib_to_hex(char * nib){ 271 | char * bits; 272 | int i; 273 | 274 | bits = calloc(sizeof(char), 5); 275 | for(i=0; i<4-strlen(nib); i++) strcat(bits,"0"); 276 | 277 | strcat(bits, nib); 278 | printf("%s\n",bits); 279 | 280 | if( strcmp(bits, "0000") == 0) return '0'; 281 | if( strcmp(bits, "0001") == 0) return '1'; 282 | if( strcmp(bits, "0010") == 0) return '2'; 283 | if( strcmp(bits, "0011") == 0) return '3'; 284 | if( strcmp(bits, "0100") == 0) return '4'; 285 | if( strcmp(bits, "0101") == 0) return '5'; 286 | if( strcmp(bits, "0110") == 0) return '6'; 287 | if( strcmp(bits, "0111") == 0) return '7'; 288 | if( strcmp(bits, "1000") == 0) return '8'; 289 | if( strcmp(bits, "1001") == 0) return '9'; 290 | if( strcmp(bits, "1010") == 0) return 'A'; 291 | if( strcmp(bits, "1011") == 0) return 'B'; 292 | if( strcmp(bits, "1100") == 0) return 'C'; 293 | if( strcmp(bits, "1101") == 0) return 'D'; 294 | if( strcmp(bits, "1110") == 0) return 'E'; 295 | if( strcmp(bits, "1111") == 0) return 'F'; 296 | 297 | fprintf(stderr, "ERROR Invalid nibble!"); 298 | exit(1); 299 | } 300 | 301 | char * hex_to_nib(char hex){ 302 | if(hex == '0') return "0000"; 303 | if(hex == '1') return "0001"; 304 | if(hex == '2') return "0010"; 305 | if(hex == '3') return "0011"; 306 | if(hex == '4') return "0100"; 307 | if(hex == '5') return "0101"; 308 | if(hex == '6') return "0110"; 309 | if(hex == '7') return "0111"; 310 | if(hex == '8') return "1000"; 311 | if(hex == '9') return "1001"; 312 | if(hex == 'A') return "1010"; 313 | if(hex == 'B') return "1011"; 314 | if(hex == 'C') return "1100"; 315 | if(hex == 'D') return "1101"; 316 | if(hex == 'E') return "1110"; 317 | if(hex == 'F') return "1111"; 318 | 319 | fprintf(stderr, "ERROR Invalid hex digit"); 320 | exit(1); 321 | } 322 | 323 | char * substr(char * str, int start, int stop){ 324 | char * ret, * t; 325 | 326 | if(stop <= start || start < 0 || stop > strlen(str)){ 327 | fprintf(stderr, "ERROR out of range"); 328 | exit(1); 329 | } 330 | 331 | ret = calloc(sizeof(char), stop - start + 1); 332 | t = str; 333 | while(t != '\0'){ 334 | printf("%s", ret); 335 | } 336 | return ret; 337 | } 338 | 339 | char * decbits(char a){ 340 | char * dst; 341 | dst = malloc(5); 342 | switch(a){ 343 | case '0': 344 | dst = "0"; 345 | break; 346 | case '1': 347 | dst = "1"; 348 | break; 349 | case '2': 350 | dst = "10"; 351 | break; 352 | case '3': 353 | dst = "11"; 354 | break; 355 | case '4': 356 | dst = "100"; 357 | break; 358 | case '5': 359 | dst = "101"; 360 | break; 361 | case '6': 362 | dst = "110"; 363 | break; 364 | case '7': 365 | dst = "111"; 366 | break; 367 | case '8': 368 | dst = "1000"; 369 | break; 370 | case '9': 371 | dst = "1001"; 372 | break; 373 | } 374 | return dst; 375 | } 376 | --------------------------------------------------------------------------------