Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cstdlib>
- #include <cstring>
- #include <cctype>
- #include <windows.h> // ZeroMemory
- #include <boost/multiprecision/cpp_int.hpp> // uint1024_t
- using namespace boost::multiprecision;
- using namespace std;
- int1024_t int1024_sqrt(int1024_t x)
- {
- register int1024_t op, res, one;
- op = x;
- res = 0;
- /* "one" starts at the highest power of four <= than the argument. */
- one = 1 << 30; /* second-to-top bit set */
- while (one > op) one >>= 2;
- while (one != 0) {
- if (op >= res + one)
- {
- op -= res + one;
- res += one << 1; // <-- faster than 2 * one
- }
- res >>= 1;
- one >>= 2;
- }
- return res;
- }
- int value(char roman)
- {
- switch(roman)
- {
- case 'I':return 1;
- case 'V':return 5;
- case 'X':return 10;
- case 'L':return 50;
- case 'C':return 100;
- case 'D':return 500;
- case 'M':return 1000;
- case 'i':return 1;
- case 'v':return 5;
- case 'x':return 10;
- case 'l':return 50;
- case 'c':return 100;
- case 'd':return 500;
- case 'm':return 1000;
- default: return 0; //if roman is not a roman numeral
- }
- }
- int1024_t from_roman(const string& input)
- {
- int1024_t sum=0;
- char prev='%';
- for(int i=(input.length()-1); i>=0; i--)
- {
- if(value(input[i])<sum && (input[i]!=prev)) {
- sum -= value(input[i]);
- prev = input[i];
- } else {
- sum += value(input[i]);
- prev = input[i];
- }
- }
- return sum;
- }
- std::string to_roman(int1024_t value)
- {
- struct romandata_t { int value; char const* numeral; };
- static romandata_t const romandata[] = {
- 1000, "M",
- 900, "CM",
- 500, "D",
- 400, "CD",
- 100, "C",
- 90, "XC",
- 50, "L",
- 40, "XL",
- 10, "X",
- 9, "IX",
- 5, "V",
- 4, "IV",
- 1, "I",
- 0, NULL }; // end marker
- std::string result;
- for (romandata_t const* current = romandata; current->value > 0; ++current)
- {
- while (value >= current->value)
- {
- result += current->numeral;
- value -= current->value;
- }
- }
- return result;
- }
- int main( void ) {
- char input[520]; //520 because (sizeof(sub1) + sizeof(sub2) + 2 potential signs + 2 potential operator characters + 1 null character (to end the string)) * 2 (for potential spaces)
- char sub1[128]; //128 because it is the size (in bytes) of int1024_t
- char sub2[128];
- unsigned short cur1;
- unsigned short cur2;
- bool sign1;
- bool sign2;
- unsigned short num1;
- unsigned short num2;
- int1024_t numeral1;
- int1024_t numeral2;
- unsigned short i;
- while (true)
- {
- ZeroMemory(&input, sizeof(input));
- ZeroMemory(&sub1, sizeof(sub1));
- ZeroMemory(&sub2, sizeof(sub2));
- num1=0;
- num2=0;
- numeral1 = 0;
- numeral2 = 0;
- i=0;
- cout << "\nCalculate: ";
- gets(input);
- if (feof(stdin)!=0) { //checks if an error has occured
- cout << "An error has occured: You have somehow entered an invalid (end-of-file) character.";
- return 0;
- }
- i = 0;
- while (value(input[i])==0)
- {
- ++i;
- }
- sign1 = (input[i-1]=='-');
- for ( cur1 = sign1; ( (num1!=sizeof(sub1))&&(input[cur1]!='+')&&(input[cur1]!='-')&&(input[cur1]!='*')&&(input[cur1]!='/')&&(input[cur1]!='|')&&(input[cur1]!='>')&&
- (input[cur1]!='^')&&(input[cur1]!='%')&&(input[cur1]!='&')&&(input[cur1]!='!')&&(input[cur1]!='~')&&(input[cur1]!='<')&&(input[cur1]!='=')&&
- (input[cur1]!='.') ); ++cur1 )
- {
- if (value(input[cur1])!=0) //makes the non-roman characters (such as spaces) be skipped
- {
- sub1[num1] = (char)toupper(input[cur1]);
- ++num1;
- }
- }
- i = cur1;
- while (value(input[i])==0)
- {
- ++i;
- }
- sign2 = (input[i-1]=='-');
- if (num1!=sizeof(sub1))
- {
- goto operator_exists;
- } else {
- cout << "An error has occured: You must put a valid operator between the two roman numerals.";
- goto end_of_while_statement;
- }
- operator_exists:
- for (cur2 = sign2; ( (num2!=sizeof(sub2)) && (input[cur2+cur1+1]!=0) ); ++cur2 )
- {
- if (value(input[cur2+cur1+1])!=0)
- {
- sub2[num2] = (char)toupper(input[cur2+cur1+1]);
- ++num2;
- }
- }
- numeral1 = ( from_roman(sub1) * (sign1?-1:1) );
- numeral2 = ( from_roman(sub2) * (sign1?-1:1) );
- switch((int)input[cur1])
- {
- case '+': {
- switch (input[cur1+1])
- {
- case '+':{
- cout << to_roman(numeral1+(++numeral2));
- goto end_of_while_statement;
- }
- case '~':{
- cout << to_roman(numeral1+(~numeral2));
- goto end_of_while_statement;
- }
- case '!':{
- cout << to_roman(numeral1+(!numeral2));
- goto end_of_while_statement;
- }
- case '=':{
- cout <<to_roman( (input[cur1+2]=='>') ? ((++numeral1)>=numeral2) : ((input[cur1+2]=='<')?((++numeral1)<=numeral2):((++numeral1)==numeral2)) );
- goto end_of_while_statement;
- }
- case '>':{
- cout << to_roman( (input[cur1+2]=='=') ? ((++numeral1)>=numeral2) : ((++numeral1)>numeral2) );
- goto end_of_while_statement;
- }
- case '<':{
- cout << to_roman( (input[cur1+2]=='=') ? ((++numeral1)<=numeral2) : ((++numeral1)<numeral2) );
- goto end_of_while_statement;
- }
- case '/':{
- cout << to_roman((++numeral1)/numeral2);
- goto end_of_while_statement;
- }
- case '*':{
- cout << to_roman((++numeral1)*numeral2);
- goto end_of_while_statement;
- }
- case '^':{
- cout << to_roman((++numeral1)^numeral2);
- goto end_of_while_statement;
- }
- case '%':{
- cout << to_roman((++numeral1)%numeral2);
- goto end_of_while_statement;
- }
- case '.':{ //in this calculator, the '.' symbol is the concatinatination operator
- char cat_chars[sizeof(sub1)+sizeof(sub2)];
- ZeroMemory(&cat_chars, sizeof(cat_chars));
- strcpy( cat_chars, to_roman(++numeral1).c_str() );
- strcat( cat_chars, to_roman(numeral2).c_str() );
- cout << cat_chars;
- goto end_of_while_statement;
- }
- default: {
- cout << to_roman(numeral1+numeral2);
- goto end_of_while_statement;
- }
- }
- }
- case '-': {
- switch (input[cur1+1])
- {
- case '+':{
- cout << to_roman(numeral1-(++numeral2));
- goto end_of_while_statement;
- }
- case '~':{
- cout << to_roman(numeral1-(~numeral2));
- goto end_of_while_statement;
- }
- case '!':{
- cout << to_roman(numeral1-(!numeral2));
- goto end_of_while_statement;
- }
- case '=':{
- cout <<to_roman( (input[cur1+2]=='>') ? ((--numeral1)>=numeral2) : ((input[cur1+2]=='<')?((--numeral1)<=numeral2):((--numeral1)==numeral2)) );
- goto end_of_while_statement;
- }
- case '>':{
- cout << to_roman( (input[cur1+2]=='=') ? ((--numeral1)>=numeral2) : ((--numeral1)>numeral2) );
- goto end_of_while_statement;
- }
- case '<':{
- cout << to_roman( (input[cur1+2]=='=') ? ((--numeral1)<=numeral2) : ((--numeral1)<numeral2) );
- goto end_of_while_statement;
- }
- case '/':{
- cout << to_roman((--numeral1)/numeral2);
- goto end_of_while_statement;
- }
- case '*':{
- cout << to_roman((--numeral1)*numeral2);
- goto end_of_while_statement;
- }
- case '^':{
- cout << to_roman((--numeral1)^numeral2);
- goto end_of_while_statement;
- }
- case '%':{
- cout << to_roman((--numeral1)%numeral2);
- goto end_of_while_statement;
- }
- case '.':{ //in this calculator, the '.' symbol is the concatinatination operator
- char cat_chars[sizeof(sub1)+sizeof(sub2)];
- ZeroMemory(&cat_chars, sizeof(cat_chars));
- strcpy( cat_chars, to_roman(--numeral1).c_str() );
- strcat( cat_chars, to_roman(numeral2).c_str() );
- cout << cat_chars;
- goto end_of_while_statement;
- }
- default: {
- cout << to_roman(numeral1-numeral2);
- goto end_of_while_statement;
- }
- }
- }
- case '/': {
- switch (input[cur1+1])
- {
- case '+':{
- cout << to_roman(numeral1/(++numeral2));
- goto end_of_while_statement;
- }
- case '~':{
- cout << to_roman(numeral1/(~numeral2));
- goto end_of_while_statement;
- }
- case '!':{
- cout << to_roman(numeral1/(!numeral2));
- goto end_of_while_statement;
- }
- case '=':{
- cout <<to_roman( (input[cur1+2]=='>') ? (int1024_sqrt(numeral1)>=numeral2) : ((input[cur1+2]=='<')?(int1024_sqrt(numeral1)<=numeral2):(int1024_sqrt(numeral1)==numeral2)) );
- goto end_of_while_statement;
- }
- case '>':{
- cout << to_roman( (input[cur1+2]=='=') ? (int1024_sqrt(numeral1)>=numeral2) : (int1024_sqrt(numeral1)>numeral2) );
- goto end_of_while_statement;
- }
- case '<':{
- cout << to_roman( (input[cur1+2]=='=') ? (int1024_sqrt(numeral1)<=numeral2) : (int1024_sqrt(numeral1)<numeral2) );
- goto end_of_while_statement;
- }
- case '/':{
- cout << to_roman(int1024_sqrt(numeral1)/numeral2);
- goto end_of_while_statement;
- }
- case '*':{
- cout << to_roman(int1024_sqrt(numeral1)*numeral2);
- goto end_of_while_statement;
- }
- case '^':{
- cout << to_roman(int1024_sqrt(numeral1)^numeral2);
- goto end_of_while_statement;
- }
- case '%':{
- cout << to_roman(int1024_sqrt(numeral1)%numeral2);
- goto end_of_while_statement;
- }
- case '.':{ //in this calculator, the '.' symbol is the concatinatination operator
- char cat_chars[sizeof(sub1)+sizeof(sub2)];
- ZeroMemory(&cat_chars, sizeof(cat_chars));
- strcpy( cat_chars, to_roman(int1024_sqrt(numeral1)).c_str() );
- strcat( cat_chars, to_roman(numeral2).c_str() );
- cout << cat_chars;
- goto end_of_while_statement;
- }
- default: {
- cout << to_roman(numeral1/numeral2);
- goto end_of_while_statement;
- }
- }
- }
- case '*': {
- switch (input[cur1+1])
- {
- case '+':{
- cout << to_roman(numeral1*(++numeral2));
- goto end_of_while_statement;
- }
- case '~':{
- cout << to_roman(numeral1*(~numeral2));
- goto end_of_while_statement;
- }
- case '!':{
- cout << to_roman(numeral1*(!numeral2));
- goto end_of_while_statement;
- }
- case '=':{
- cout <<to_roman( (input[cur1+2]=='>') ? ((numeral1*numeral1)>=numeral2) : ((input[cur1+2]=='<')?((numeral1*numeral1)<=numeral2):((numeral1*numeral1)==numeral2)) );
- goto end_of_while_statement;
- }
- case '>':{
- cout << to_roman( (input[cur1+2]=='=') ? ((numeral1*numeral1)>=numeral2) : ((numeral1*numeral1)>numeral2) );
- goto end_of_while_statement;
- }
- case '<':{
- cout << to_roman( (input[cur1+2]=='=') ? ((numeral1*numeral1)<=numeral2) : ((numeral1*numeral1)<numeral2) );
- goto end_of_while_statement;
- }
- case '/':{
- cout << to_roman((numeral1*numeral1)/numeral2);
- goto end_of_while_statement;
- }
- case '*':{
- cout << to_roman((numeral1*numeral1)*numeral2);
- goto end_of_while_statement;
- }
- case '^':{
- cout << to_roman((numeral1*numeral1)^numeral2);
- goto end_of_while_statement;
- }
- case '%':{
- cout << to_roman((numeral1*numeral1)%numeral2);
- goto end_of_while_statement;
- }
- case '.':{ //in this calculator, the '.' symbol is the concatinatination operator
- char cat_chars[sizeof(sub1)+sizeof(sub2)];
- ZeroMemory(&cat_chars, sizeof(cat_chars));
- strcpy( cat_chars, to_roman(numeral1*numeral1).c_str() );
- strcat( cat_chars, to_roman(numeral2).c_str() );
- cout << cat_chars;
- goto end_of_while_statement;
- }
- default: {
- cout << to_roman(numeral1*numeral2);
- goto end_of_while_statement;
- }
- }
- }
- case '^': {
- switch (input[cur1+1])
- {
- case '+':{
- cout << to_roman(numeral1^(++numeral2));
- goto end_of_while_statement;
- }
- case '~':{
- cout << to_roman(numeral1^(~numeral2));
- goto end_of_while_statement;
- }
- case '!':{
- cout << to_roman(numeral1^(!numeral2));
- goto end_of_while_statement;
- }
- case '=':{
- cout <<to_roman( (input[cur1+2]=='>') ? ((numeral1^(numeral1<<1))>=numeral2) : ((input[cur1+2]=='<')?((numeral1^(numeral1<<1))<=numeral2):((numeral1^(numeral1<<1))==numeral2)) );
- goto end_of_while_statement;
- }
- case '>':{
- cout << to_roman( (input[cur1+2]=='=') ? ((numeral1^(numeral1<<1))>=numeral2) : ((numeral1^(numeral1<<1))>numeral2) );
- goto end_of_while_statement;
- }
- case '<':{
- cout << to_roman( (input[cur1+2]=='=') ? ((numeral1^(numeral1<<1))<=numeral2) : ((numeral1^(numeral1<<1))<numeral2) );
- goto end_of_while_statement;
- }
- case '/':{
- cout << to_roman((numeral1^(numeral1<<1))/numeral2);
- goto end_of_while_statement;
- }
- case '*':{
- cout << to_roman((numeral1^(numeral1<<1))*numeral2);
- goto end_of_while_statement;
- }
- case '^':{
- cout << to_roman((numeral1^(numeral1<<1))^numeral2);
- goto end_of_while_statement;
- }
- case '%':{
- cout << to_roman((numeral1^(numeral1<<1))%numeral2);
- goto end_of_while_statement;
- }
- case '.':{ //in this calculator, the '.' symbol is the concatinatination operator
- char cat_chars[sizeof(sub1)+sizeof(sub2)];
- ZeroMemory(&cat_chars, sizeof(cat_chars));
- strcpy( cat_chars, to_roman(numeral1*numeral1).c_str() );
- strcat( cat_chars, to_roman(numeral2).c_str() );
- cout << cat_chars;
- goto end_of_while_statement;
- }
- default: {
- cout << to_roman(numeral1^numeral2);
- goto end_of_while_statement;
- }
- }
- }
- case '%': {
- switch (input[cur1+1])
- {
- case '+':{
- cout << to_roman(numeral1%(++numeral2));
- goto end_of_while_statement;
- }
- case '~':{
- cout << to_roman(numeral1%(~numeral2));
- goto end_of_while_statement;
- }
- case '!':{
- cout << to_roman(numeral1%(!numeral2));
- goto end_of_while_statement;
- }
- case '=':{
- cout <<to_roman( (input[cur1+2]=='>') ? ((numeral1%numeral2)>=numeral2) : ((input[cur1+2]=='<')?((numeral1%numeral2)<=numeral2):((numeral1%numeral2)==numeral2)) );
- goto end_of_while_statement;
- }
- case '>':{
- cout << to_roman( (input[cur1+2]=='=') ? ((numeral1%numeral2)>=numeral2) : ((numeral1%numeral2)>numeral2) );
- goto end_of_while_statement;
- }
- case '<':{
- cout << to_roman( (input[cur1+2]=='=') ? ((numeral1%numeral2)<=numeral2) : ((numeral1%numeral2)<numeral2) );
- goto end_of_while_statement;
- }
- case '/':{
- cout << to_roman((numeral1%numeral2)/numeral2);
- goto end_of_while_statement;
- }
- case '*':{
- cout << to_roman((numeral1%numeral2)*numeral2);
- goto end_of_while_statement;
- }
- case '^':{
- cout << to_roman((numeral1%numeral2)^numeral2);
- goto end_of_while_statement;
- }
- case '%':{
- cout << to_roman((numeral1%numeral2)%numeral2);
- goto end_of_while_statement;
- }
- case '.':{ //in this calculator, the '.' symbol is the concatinatination operator
- char cat_chars[sizeof(sub1)+sizeof(sub2)];
- ZeroMemory(&cat_chars, sizeof(cat_chars));
- strcpy( cat_chars, to_roman(numeral1%numeral2).c_str() );
- strcat( cat_chars, to_roman(numeral2).c_str() );
- cout << cat_chars;
- goto end_of_while_statement;
- }
- default: {
- cout << to_roman(numeral1%numeral2);
- goto end_of_while_statement;
- }
- }
- }
- case '.': {
- char cat_chars[sizeof(sub1)+sizeof(sub2)];
- ZeroMemory(&cat_chars, sizeof(cat_chars));
- strcpy( cat_chars, to_roman(numeral1).c_str() );
- strcat( cat_chars, to_roman(numeral2).c_str() );
- cout << cat_chars;
- goto end_of_while_statement;
- }
- case '&': {
- switch (input[cur1+1])
- {
- case '+':{
- cout << to_roman(numeral1&(++numeral2));
- goto end_of_while_statement;
- }
- case '~':{
- cout << to_roman(numeral1&(~numeral2));
- goto end_of_while_statement;
- }
- case '!':{
- cout << to_roman(numeral1&(!numeral2));
- goto end_of_while_statement;
- }
- case '/':{
- cout << to_roman((numeral1&numeral2)/numeral2);
- goto end_of_while_statement;
- }
- case '*':{
- cout << to_roman((numeral1&numeral2)*numeral2);
- goto end_of_while_statement;
- }
- case '^':{
- cout << to_roman((numeral1&numeral2)^numeral2);
- goto end_of_while_statement;
- }
- case '%':{
- cout << to_roman((numeral1&numeral2)%numeral2);
- goto end_of_while_statement;
- }
- case '.':{ //in this calculator, the '.' symbol is the concatinatination operator
- char cat_chars[sizeof(sub1)+sizeof(sub2)];
- ZeroMemory(&cat_chars, sizeof(cat_chars));
- strcpy( cat_chars, to_roman(numeral1&numeral2).c_str() );
- strcat( cat_chars, to_roman(numeral2).c_str() );
- cout << cat_chars;
- goto end_of_while_statement;
- }
- default: {
- cout << to_roman(numeral1&numeral2);
- goto end_of_while_statement;
- }
- }
- }
- case '|': {
- switch (input[cur1+1])
- {
- case '+':{
- cout << to_roman(numeral1|(++numeral2));
- goto end_of_while_statement;
- }
- case '~':{
- cout << to_roman(numeral1|(~numeral2));
- goto end_of_while_statement;
- }
- case '!':{
- cout << to_roman(numeral1|(!numeral2));
- goto end_of_while_statement;
- }
- case '/':{
- cout << to_roman((numeral1|numeral2)/numeral2);
- goto end_of_while_statement;
- }
- case '*':{
- cout << to_roman((numeral1|numeral2)*numeral2);
- goto end_of_while_statement;
- }
- case '^':{
- cout << to_roman((numeral1|numeral2)^numeral2);
- goto end_of_while_statement;
- }
- case '%':{
- cout << to_roman((numeral1|numeral2)%numeral2);
- goto end_of_while_statement;
- }
- case '.':{ //in this calculator, the '.' symbol is the concatinatination operator
- char cat_chars[sizeof(sub1)+sizeof(sub2)];
- ZeroMemory(&cat_chars, sizeof(cat_chars));
- strcpy( cat_chars, to_roman(numeral1|numeral2).c_str() );
- strcat( cat_chars, to_roman(numeral2).c_str() );
- cout << cat_chars;
- goto end_of_while_statement;
- }
- default: {
- cout << to_roman(numeral1|numeral2);
- goto end_of_while_statement;
- }
- }
- }
- }
- end_of_while_statement:
- cout << "\n";
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement