The Daily WTF: Curious Perversions in Information Technology
Welcome to TDWTF Forums Sign in | Join | Help
in Search

Post the function you are most proud of.

Last post 06-01-2007 4:23 PM by kupior. 116 replies.
Page 2 of 3 (117 items) < Previous 1 2 3 Next >
Sort Posts: Previous Next
  • 05-15-2007 10:48 AM In reply to

    Re: Post the function you are most proud of.

    Domster:
    I went down the mathematical/logical road, and implemented the axioms of Robinson arithmetic (kinda similar to Peano arithmetic, if you've heard of that, but less powerful (and therefore incomplete and consistent)).
    If you believe Gödel, no system of axioms can be both complete and consistent.
  • 05-15-2007 11:08 AM In reply to

    Re: Post the function you are most proud of.

    I am a bit proud (ashamed) of how I handled decimals...

    union
    {
     float f;
     unsigned char c[];
    } u;

    float maf(const char* s)
    {
     int O = daZ((int)s[1],(int)'0');
     switch (O)
     {
     case 1:
      u.c[3] = (unsigned char)dal(59, 0);
      u.c[2] = (unsigned char)dal(204, 0);
      u.c[1] = (unsigned char)dal(204, 0);
      u.c[0] = (unsigned char)dal(204, 0);
      break;
     case 2:
      u.c[3] = (unsigned char)dal(62, 0);
      u.c[2] = (unsigned char)dal(75, 0);
      u.c[1] = (unsigned char)dal(204, 0);
      u.c[0] = (unsigned char)dal(204, 0);
      break;
     case 3:
      u.c[3] = (unsigned char)dal(65, 0);
      u.c[2] = (unsigned char)dal(152, 0);
      u.c[1] = (unsigned char)dal(150, 0);
      u.c[0] = (unsigned char)dal(153, 0);
     case 4:
      u.c[3] = (unsigned char)dal(68, 0);
      u.c[2] = (unsigned char)dal(204, 0);
      u.c[1] = (unsigned char)dal(204, 0);
      u.c[0] = (unsigned char)dal(204, 0);
      break;
     case 5:
      u.c[3] = (unsigned char)dal(63, 0);
      u.c[2] = (unsigned char)dal(0, 0);
      u.c[1] = (unsigned char)dal(0, 0);
      u.c[0] = (unsigned char)dal(0, 0);
      break;
     case 6:
      u.c[3] = (unsigned char)dal(63, 0);
      u.c[2] = (unsigned char)dal(25, 0);
      u.c[1] = (unsigned char)dal(153, 0);
      u.c[0] = (unsigned char)dal(154, 0);
      break;
     case 7:
      u.c[3] = (unsigned char)dal(49, 0);
      u.c[2] = (unsigned char)dal(51, 0);
      u.c[1] = (unsigned char)dal(51, 0);
      u.c[0] = (unsigned char)dal(51, 0);
     case 8:
      u.c[3] = (unsigned char)dal(68, 0);
      u.c[2] = (unsigned char)dal(75, 0);
      u.c[1] = (unsigned char)dal(204, 0);
      u.c[0] = (unsigned char)dal(204, 0);
      break;
     case 9:
      u.c[3] = (unsigned char)dal(53, 0);
      u.c[2] = (unsigned char)dal(101, 0);
      u.c[1] = (unsigned char)dal(102, 0);
      u.c[0] = (unsigned char)dal(102, 0);
      break;
     }
     return u.f;
    }

    Yes, I know case 0 is missing and that only returns the correct float for .5 or .6.

  • 05-15-2007 11:11 AM In reply to

    Re: Post the function you are most proud of.

    Thuktun:
    If you believe Gödel, no system of axioms can be both complete and consistent.

    Godel's arguments are little more than a misunderstanding, and, perhaps, a form of argument by theft of language.
  • 05-15-2007 11:49 AM In reply to

    • wacco
    • Not Ranked
    • Joined on 05-13-2007
    • Posts 11

    Re: Post the function you are most proud of.

    Most of my WTFs are the overenthousiastic comments and triple-redundant architecture in use, but if it comes down to code snippets I personally enjoyed this part;

    /* Following two functions provide functionality which isn't provided by the 

     * stack implementation, but that doesn't matter anyway because only this BNF

     * parser really needs them, so I just wrote these wrappers around the stack

     * code.

     */


    /* Peek at next item */

    char *peekNext() {

      char *cur = NULL, *cur2 = NULL;

      if(cur = tmp->popr(tmp)) {

        stack *tmp3 = new_stack();

        while(cur2 = tmp->popr(tmp))

          tmp3->push(tmp3, cur2);

        tmp->push(tmp, cur);

        while(cur2 = tmp3->popr(tmp3))

          tmp->push(tmp, cur2);

        free(tmp3);

      }

      return cur;

    }


    The stack behaves like a class, except it's a typedef. And uses a linked list for values. X_x

  • 05-15-2007 11:51 AM In reply to

    • JCM
    • Not Ranked
    • Joined on 03-16-2006
    • Posts 23

    Re: Post the function you are most proud of.

    FETs on only act like voltage controlled resistors if you bias them into their active region.  They can be biased to either be cutoff or saturated as well.  In this switching capacity they look just like solid state switches (until you get to a high enough voltage across them and they ionize, then they go *poof*).  In this switching operating mode, the drain and source would be interchangeable.
  • 05-15-2007 12:01 PM In reply to

    • TylerK
    • Not Ranked
    • Joined on 05-15-2007
    • Posts 4

    Re: Post the function you are most proud of.

    void DoOperation(char operation, float op1, float op2)
    {
            float r;

            switch (operation)
            {
            case '+':
                    r = op1 + op2;
                    break;
            case '-':
                    r = op1 - op2;
                    break;
            case '*':
                    r = op1 * op2;
                    break;
            case '/':
                    r = (int)op1/(int)op2;
                    r = op1 / op2;
                    break;
            default:
                    r = op2;
            }

            sprintf( (char *) *(int *) &r, "paula = brillant");
    }

  • 05-15-2007 12:07 PM In reply to

    Re: Post the function you are most proud of.

    It took me a little while to see what you did there. Writing "paula = brillant" into memory locations addressed by the results of operations is pretty tech. The question is can it pass all the test cases without overwriting itself to the point that it no longer works or writing out of segment?
  • 05-15-2007 12:37 PM In reply to

    Re: Post the function you are most proud of.

    You guys have me beat, but here's my two cents.  Though the true magic of using fork() and pipe() for a simulation of string concatenation (none is actually done) is either lost or in another file, I show you this marvelous substitute for a client-server architecture.  Notice the comment: it is one of a precious few. 

    Also, a.out forks and execs ... another a.out!

     

    RequestFactoryReturnValue
    RequestFactoryFullRequest_emitFullRequest(RequestFactoryFullRequest theFullRequest)
    {
    #define WRITE_END pfd[1]
    #define READ_END  pfd[0]
         GIOChannel *theOutChannel;
         GError *theError = 0;
         int pfd[2];
         pid_t theProcessID;

         if (g_file_test("./socket", G_FILE_TEST_EXISTS) == FALSE)
              return REQUEST_FACTORY_RETURN_UNSUCCESSFUL;

         if (pipe(pfd) == -1)
              return REQUEST_FACTORY_UNSUCCESSFUL_RETURN;

         g_print("bananas\n");
         theProcessID = fork();
         if (theProcessID == -1)
              return REQUEST_FACTORY_UNSUCCESSFUL_RETURN;
         else if (theProcessID == 0) {
              char c;
              FILE *out = fopen("./chain1", "w");
              close(WRITE_END);
              while (read(READ_END, &c, 1) == 1) {
                   g_print(g_strdup_printf("%c", c));
                   fputc(c, out);
                   if (c == '\n')
                        break;
              }
              g_print("executing ./a.out...\n");
              fclose(out);
              fclose(stdin);
              fclose(stdout);
              close(READ_END);
              stdin = fopen("./chain1", "r");
              stdout = fopen("./chain2", "w");
              execl("./a.out", "./a.out", (char *) 0);
              // system("./a.out < ./socket");
              _exit(0);
         } else {
              theOutChannel = g_io_channel_unix_new(WRITE_END);
              if (theOutChannel == 0 || theError != 0)
                   return REQUEST_FACTORY_RETURN_UNSUCCESSFUL;

              theError = 0;
              g_io_channel_write_chars(theOutChannel, theFullRequest.theRequestString->str,
                                       theFullRequest.theRequestString->len, 0,
                                       &theError);
              if (theError != 0)
                   theError = 0;
              g_io_channel_shutdown(theOutChannel, TRUE, &theError);
              close(READ_END);
              waitpid(theProcessID, 0, 0);
         }
         return REQUEST_FACTORY_RETURN_SUCCESSFUL;
    }

  • 05-15-2007 12:50 PM In reply to

    • todd
    • Not Ranked
    • Joined on 04-29-2007
    • Posts 9

    Re: Post the function you are most proud of.

     This is the code for emulating the "ld" operation from the assembly generated by compiling the arithmetic expression.  There is another interpreter that evaluates this lisp-like language.

    std::string CPU::simcode("(dotimes i (len code) "
                             " (setf inst (nth i code))"
                             " (if (eq (nth 0 inst) ld)" // Ld opcode
                             "  (dotimes n 1"
                             "   (if (eq (nth 2 inst) A)"
                             "    (setf areg (nth 1 inst)))"
                             "   (if (eq (nth 2 inst) B)"
                             "    (setf breg (nth 1 inst)))"
                             "   (if (eq (nth 2 inst) C)"
                             "    (setf creg (nth 1 inst)))"
                             "   (if (eq (nth 2 inst) D)"
                             "    (setf dreg (nth 1 inst)))"
                             "   (if (eq (nth 2 inst) E)"
                             "    (setf ereg (nth 1 inst)))))"
    .... continues for several hundred lines for the rest of the operations supported by my virtual machine...

     

    And here is the assembly after it's been translated to a list for the lispy language (for "1+2*3=", notice that it handles operator precedence correctly):


     (setf code (list
      (list ld 3.000000 D  )
      (list ld 2.000000 A  )
      (list mul  A  D  )
      (list mov  A  B  )
      (list ld 1.000000 A  )
      (list add  A  B  )
     ))

     

    So the user enters an arithmetic expression, it get's lexed/parsed/ and compiled to assembly.  A peephole optimizer runs on the assembly producing equivalent but faster assembly. This is converted to a "setf code"  statement that sets the code variable to a list of lists which contain the assembly operation and data. This is concatenated with the string that contains the source for the CPU simulator in lispy, which is then lexed/parsed/interpreted by the lispy interpreter.  There's a few more nifty things about the interpreter (involving chess boards and arbitrary precision arithmetic) but that's the gist of it.

     

  • 05-15-2007 2:01 PM In reply to

    Re: Post the function you are most proud of.

    The guts of my third submission:

    static void perform_operation(double first_value, double second_value, int operation)
    {
            GThread                                                 *calculation_thread;
            GThread                                                 *display_thread;
            GThreadFunc                                             thread_function;
            gboolean                                                thread_complete = FALSE;
            struct  calculation_parameters  *thread_data;

    #if 0   /* Bugger it.  Getting this to work properly is too hard. */
            /* Shortcut to handle division by zero */
            if(BUTTON_DIV == operation && second_value == 0)
            {
                    gtk_entry_set_text(GTK_ENTRY(display_box), "Err");
                    input_value = 0.0;                      /* NOTE: Violates IEEE 754: division by zero should produce the appropriate signed infinity */
            }
            else
            {
                    /* Disable the UI */
            //      g_signal_handler_block

                    /* Prepare the calculation thread */
                    switch(operation)
                    {
                            case BUTTON_PLUS:
                                    thread_function = add;
                                    break;
                            case BUTTON_MINUS:
                                    thread_function = subtract;
                                    break;
                            case BUTTON_TIMES:
                                    thread_function = multiply;
                                    break;
                            case BUTTON_DIV:
                                    thread_function = divide;
                                    break;
                            default:
                                    /* This is an error condition, but it can't happen */
                                    g_print("Impossible: Operation %d requested.\n", operation);
                                    return;
                    }

                    thread_data = malloc(sizeof(struct calculation_parameters));

                    thread_data->value1 = first_value;
                    thread_data->value2 = second_value;
                    thread_data->result = 0.0;
                    thread_data->confidence_interval = pow(0.1, gtk_range_get_value(GTK_RANGE(accuracy_slider)));

                    g_mutex_lock(results_mutex);
                    calculations_complete = FALSE;
                    current_result = 0.0;
                    current_confidence_interval = 1.0;
                    g_mutex_unlock(results_mutex);

                    /* Fire the calculation thread */
                    calculation_thread = g_thread_create(thread_function, (gpointer)thread_data , FALSE, NULL);

                    g_timeout_add(100, display_results, (gpointer)thread_data);
            }
    #else
            if(operation == BUTTON_EQUAL)
            {
                    switch(counter)
                    {
                            case 0:
                                    gtk_entry_set_text(GTK_ENTRY(display_box), "2");
                                    break;
                            case 1:
                                    gtk_entry_set_text(GTK_ENTRY(display_box), "1");
                                    break;
                            case 2:
                                    gtk_entry_set_text(GTK_ENTRY(display_box), "2");
                                    break;
                            case 3:
                                    gtk_entry_set_text(GTK_ENTRY(display_box), "1");
                                    break;
                            case 4:
                                    gtk_entry_set_text(GTK_ENTRY(display_box), "Err");
                                    break;
                            case 5:
                                    gtk_entry_set_text(GTK_ENTRY(display_box), "-1");
                                    break;
                            case 6:
                                    gtk_entry_set_text(GTK_ENTRY(display_box), "11");
                                    break;
                            case 7:
                                    gtk_entry_set_text(GTK_ENTRY(display_box), "666");
                                    break;
                            case 8:
                                    gtk_entry_set_text(GTK_ENTRY(display_box), "1337");
                                    break;
                            case 9:
                                    gtk_entry_set_text(GTK_ENTRY(display_box), "12321");
                                    break;
                            case 10:
                                    gtk_entry_set_text(GTK_ENTRY(display_box), "200695");
                                    break;
                            case 11:
                                    gtk_entry_set_text(GTK_ENTRY(display_box), "100100");
                                    break;
                            case 12:
                                    gtk_entry_set_text(GTK_ENTRY(display_box), "11110");
                                    break;
                            case 13:
                                    gtk_entry_set_text(GTK_ENTRY(display_box), "0.5");
                                    break;
                            case 14:
                                    gtk_entry_set_text(GTK_ENTRY(display_box), "-100000");
                                    break;
                            case 15:
                                    gtk_entry_set_text(GTK_ENTRY(display_box), "205688");
                                    break;
                            case 16:
                                    gtk_entry_set_text(GTK_ENTRY(display_box), "6");
                                    break;
                            case 17:
                                    gtk_entry_set_text(GTK_ENTRY(display_box), "37500");
                                    break;
                            case 18:
                                    gtk_entry_set_text(GTK_ENTRY(display_box), "100");
                                    break;
                            case 19:
                                    gtk_entry_set_text(GTK_ENTRY(display_box), "0.6");
                                    break;
                            case 20:
                                    gtk_entry_set_text(GTK_ENTRY(display_box), "579");
                                    break;
                            case 21:
                                    gtk_entry_set_text(GTK_ENTRY(display_box), "523769");
                                    break;
                            case 22:
                                    gtk_entry_set_text(GTK_ENTRY(display_box), "6283");
                                    break;
                            case 23:
                                    gtk_entry_set_text(GTK_ENTRY(display_box), "3110");
                                    break;
                            case 24:
                                    gtk_entry_set_text(GTK_ENTRY(display_box), "-16742");
                                    break;
                            case 25:
                                    gtk_entry_set_text(GTK_ENTRY(display_box), "90736");
                                    break;
                            case 26:
                                    gtk_entry_set_text(GTK_ENTRY(display_box), "7");
                                    break;
                            case 27:
                                    gtk_entry_set_text(GTK_ENTRY(display_box), "8034");
                                    break;
                            case 28:
                                    gtk_entry_set_text(GTK_ENTRY(display_box), "0");
                                    break;

                            default:
                                    gtk_entry_set_text(GTK_ENTRY(display_box), "FILE_NOT_FOUND");
                                    break;
                    }
                    counter++;
            }
    #endif
    }

  • 05-15-2007 2:07 PM In reply to

    • TylerK
    • Not Ranked
    • Joined on 05-15-2007
    • Posts 4

    Re: Post the function you are most proud of.

    Welbog:
    It took me a little while to see what you did there. Writing "paula = brillant" into memory locations addressed by the results of operations is pretty tech. The question is can it pass all the test cases without overwriting itself to the point that it no longer works or writing out of segment?

    Yes, in fact I count on it segfaulting on every test case. Here is the signal handler for SIGSEGV:

    void Result(int signum, siginfo_t *sigInfo, void *ptr) {
            siglongjmp(ans_env, (int)sigInfo);
    }
     

  • 05-15-2007 2:40 PM In reply to

    Re: Post the function you are most proud of.


    You did realize that in order to win you had to *pass* the test cases, right?
    Agile Team-Oriented Waterfall-Centric Cowboy Coder.
  • 05-15-2007 2:46 PM In reply to

    • JCM
    • Not Ranked
    • Joined on 03-16-2006
    • Posts 23

    Re: Post the function you are most proud of.

    The guts of my third submission:
    THIRD? I barely had time to do one! And when I talk to colleagues at work about it, they think I must not be working hard enough if I have time/energy/will to enter a contest like this!
  • 05-15-2007 3:06 PM In reply to

    Re: Post the function you are most proud of.

    Whiskey Tango Foxtrot? Over.:

    You did realize that in order to win you had to *pass* the test cases, right?

    This just proves that you didn't understand his reply ;)  

    OMGWTF - Are you enterprisey enough?
  • 05-15-2007 3:07 PM In reply to

    • TylerK
    • Not Ranked
    • Joined on 05-15-2007
    • Posts 4

    Re: Post the function you are most proud of.

    Whiskey Tango Foxtrot? Over.:

    You did realize that in order to win you had to *pass* the test cases, right?

    Yep!

    I thought it was obvious, but here's how it works:

    1. Set up signal handlers for SIGSEGV and SIGFPE. The signal handlers contain a longjmp to a saved environment. The longjmp for a numeric result also returns a pointer to a siginfo_t (as an integer).
    2. Upon clicking a calculation button:
        a. save environment
        b. check if we are being called from longjmp - if so, set display to "Err"
        c. save environment 
        d. check if we are being called from longjmp - if so, set up a siginfo_t using the return value from setjmp as a siginfo_t pointer, then cast the si_addr member of siginfo_t to a float (using type punning), and set the display
        e. otherwise, enter the void function DoOperation
    3. perform the operation normally and store in a float
    4. if division, attempt to perform integer division first in order to trigger SIGFPE if applicable
    5. attempt to write to the memory location that corresponds to the float representation of the result
    6. this should cause a segfault, triggering the SIGSEGV handler
     

     

  • 05-15-2007 3:12 PM In reply to

    Re: Post the function you are most proud of.

    My best/worst function has to be my division. Note that I am storing and processing numbers as strings with the order of the digits backwards. I have managed to come up with a valid use of true/false/maybe and abuse logic by gotoing from the if to the else block. My second best function is the subtraction which I refactored from 2 medium length functions into 144 functions of around 5 lines each.

    enum advancedboolean
    {
        True,
        False,
        Maybe, // not enough info to decide yet
        Both, // unlikely, but defined just in case
        Neither, // the opposite of Both
        FILE_NOT_FOUND
    };
    // I seem to have to define this in each cpp file - WTF?!

    string DoDiv(string op1, string op2, int& isErr)
    {
        // returns the quotient of op1 and op2

        // maximum loop depth to stop an infinite loop
        long emergencystop = 7500;
        
        // set isErr to One if op2 is zero, or Zero, initially 0.
        isErr = 0;

        // local copy of op1 & op2, the r is for reverse, ie the number is backwards
        string op1r = op1 + "0000000000000000000"; // 20x0
        string op2r = op2 + "0000000000000000000"; // 20x0

        string total = "000000000000000000000000";

        /*
        OK, first lets make sure that we don't have a divide by zero
        type of problem. This is the only error checking done.
        */

        if (iszero(op2r))
        {
            isErr = 1;
        }

        // now we have 1 in isErr if we will get a div by zero error

        // time to tell the luser what they have done wrong

        if (isErr == 1)
        {
            MessageBox(NULL, TEXT("KABOOM!!!"),TEXT("Fuck off!"), MB_OK);
            MessageBox(NULL, TEXT("Congratulations, you have just tried to divide by zero."),TEXT("Fuck off!"), MB_OK);
        
            // TODO: Make the following statements random
            // Importance: Low

            MessageBox(NULL, TEXT("Don't let you mind wander\n - it's far too small to be let out on its own"),TEXT("Fuck off!"), MB_OK);
            MessageBox(NULL, TEXT("Brains aren't everything.\nIn fact in your case they're nothing"),TEXT("Fuck off!"), MB_OK);
            MessageBox(NULL, TEXT("Are you always this stupid or are you making a special effort today?"),TEXT("Fuck off!"), MB_OK);
            //MessageBox(NULL, TEXT("Your mind is so open - so open that ideas simply pass through it."),TEXT("Fuck off!"), MB_OK);
            MessageBox(NULL, TEXT("Are your parents siblings?"),TEXT("Fuck off!"), MB_OK);
            MessageBox(NULL, TEXT("Calling you stupid would be an insult to stupid people."),TEXT("Fuck off!"), MB_OK);
            //MessageBox(NULL, TEXT("Do you still love nature, despite what it did to you?"),TEXT("Fuck off!"), MB_OK);
            MessageBox(NULL, TEXT("Are you by chance, a few rows short of a spreadsheet?"),TEXT("Fuck off!"), MB_OK);

            MessageBox(NULL, TEXT("Oh yes, I almost forgot..."),TEXT("Fuck off!"), MB_OK);
            MessageBox(NULL, TEXT("Err"),TEXT("Fuck off!"), MB_OK);

            return "Err";
        }

        /*

        Time for sanity check number two, If the first number is zero
        then the answer will also be zero, checking it here will avoid silly
        maths later. eg. is 0 > 0 and infinite loops.

        */

        if (iszero(op1r))
        {
            return "0";
        }

        /*
        Check for x/x = 1. saves a lot of time when its easier to do equals.
        */

        if (op2r == op1r)
        {
            return "1";
        }

        /*
        
        Now its time for some actual division. In order to have maximum number of decimals we
        move the number over until we have 14 chars.

        Note we are leaving one space for inserting a decimal point later.

        Shiftstatus holds how far its moved and therefore how far its got to move back.

        Do this means that we are only dividing whole numbers and we don't have to worry about
        decimal points getting in the way as we add these in later

        */

        int shiftstatus = 0; // how far over
        for (int p=0; p < 14; p++)
        {
            if (op1r[13] == '0')
            {
                shiftstatus++;
                op1r = shiftup(op1r);
            }
        }

        /*
        The might be a slight bug if op1r is already 14 or 15 chars.
        Never mind, we hopefully won't have numbers that big very often.

        OK, lets start division using the 2-4-8 doubles method.
        http://www.doubledivision.org/

        This will be a lot quicker than trying to loop doing minus.

        It should also be easier than long division as no division is
        needed. It simply uses multiplication by known factors and subtraction.

        While its a very simple method on paper its slightly trickier to implement in code.
        The majority of the WTFs will be in this code!
        */

        string tempshift = "0000000000000000";
        string tempshift2 = "0000000000000000";

        string times1 = op2;
        string times2 = DoMul(op2,"2", isErr);
        string times4 = DoMul(op2,"4", isErr);
        string times8 = DoMul(op2,"8", isErr);

        int i=0;
        int difference = 0; // first try lining up the numbers, this indicates an offset if needed.
        advancedboolean stopnow = False; // loop control
        string attempt; // temp for calcs

        do
        {
            emergencystop--; // for when (not if) we get stuck in an infinite loop
            difference = 0;
            
            // I would never normally consider gotos, however this function
            // is so screwed up they actually make sense!
    tryagain:

            // align to correct digits
            i = lengthofstring(op1r) - lengthofstring(times8) - difference;
            if (i < 0)
            {
                // no room to shift, see if the next number is smaller
                i = lengthofstring(op1r) - lengthofstring(times4) - difference;
                if (i < 0)
                {
                    // no room to shift, see if the next number is smaller
                    i = lengthofstring(op1r) - lengthofstring(times2) - difference;
                    if (i < 0)
                    {
                        // no room to shift, see if the next number is smaller
                        i = lengthofstring(op1r) - lengthofstring(op2r) - difference;
                        if (i < 0)
                        {
                            // crap, we can't move the number
                            stopnow=True;
                            i = 0;
                        }
                    }
                }
            }

            tempshift = times8;
            tempshift2 = "8000000000000000";
            for (int j=0; j < i; j++)
            {
                tempshift = shiftup(tempshift);
                tempshift2 = shiftup(tempshift2);
            }
            if ((isgreaterthan(trimstr(op1r), trimstr(tempshift))) || (trim2(trimstr(op1r)) == trim2(trimstr(tempshift))))
            {
                /*
                OK, we should be able to subtract as op1r is bigger
                or equal to what we are taken away, however the answer
                can    not always be trusted, so we will try to take it
                away and see if we get a negative number.
                */
                attempt = DoSub(op1r, tempshift);
                if (chrinstr(attempt, '-'))
                {
                    // we have a negative number
                    // this should never happen, but it does!
                    stopnow = Maybe;
                    // OK, we shouldn't be here, so lets pretend
                    // "if" is false and jump to the "else" statement
                    goto else0;
                }
                else
                {
                    total = DoAdd(total, tempshift2);
                    op1r = attempt;
                }
                if ((lengthofstring(trimstr(op1r)) == 1) && (op1r[0] == '0'))
                    {
                        stopnow = True;
                    }
            }
            else
            {
    else0:
                tempshift = times4;
                tempshift2 = "4000000000000000";
                for (int k=0; k < i; k++)
                {
                    tempshift = shiftup(tempshift);
                    tempshift2 = shiftup(tempshift2);
                    // if op1r = 0 then we have finnished
                }
                if (((isgreaterthan(trimstr(tempshift), trimstr(op1r)))) || (trim2(trimstr(op1r)) == trim2(trimstr(tempshift))))
                {
                    /*
                    OK, we should be able to subtract as op1r is bigger
                    or equal to what we are taken away, however the answer
                    can    not always be trusted, so we will try to take it
                    away and see if we get a negative number.
                    */
                    attempt = DoSub(op1r, tempshift);
                    if (chrinstr(attempt, '-'))
                    {
                        // we have a negative number
                        // this should never happen, but it does!
                        stopnow = Maybe;
                        // OK, we shouldn't be here, so lets pretend
                        // if is false and jump to the else statement
                        goto else1;
                    }
                    else
                    {
                        total = DoAdd(total, tempshift2);
                        op1r = attempt;
                    }
                    if ((lengthofstring(trimstr(op1r)) == 1) && (op1r[0] == '0'))
                    {
                        stopnow = True;
                    }                
                }
                else
                {
    else1:
                    tempshift = times2;
                    tempshift2 = "2000000000000000";
                    for (int m=0; m < i; m++)
                    {
                        tempshift = shiftup(tempshift);
                        tempshift2 = shiftup(tempshift2);
                        //MessageBox(NULL, TEXT("times2"),TEXT("Divide"), MB_OK);
                    }
                    if (((isgreaterthan(trimstr(tempshift), trimstr(op1r)))) || (trim2(trimstr(op1r)) == trim2(trimstr(tempshift))))
                    {
                        /*
                        OK, we should be able to subtract as op1r is bigger
                        or equal to what we are taken away, however the answer
                        can    not always be trusted, so we will try to take it
                        away and see if we get a negative number.
                        */
                        attempt = DoSub(op1r, tempshift);
                        if (chrinstr(attempt, '-'))
                        {
                            // we have a negative number
                            // this should never happen, but it does!
                            stopnow = Maybe;
                            // OK, we shouldn't be here, so lets pretend
                            // if is false and jump to the else statement
                            goto else2;
                        }
                        else
                        {
                            total = DoAdd(total, tempshift2);
                            op1r = attempt;
                        }
                        if ((lengthofstring(trimstr(op1r)) == 1) && (op1r[0] == '0'))
                        {
                            stopnow = True;
                        }
                    }
                    else
                    {
    else2:
                        tempshift = op2r;
                        tempshift2 = "1000000000000000";
                        for (int n=0; n < i; n++)
                        {
                            tempshift = shiftup(tempshift);
                            tempshift2 = shiftup(tempshift2);
                        }
                        if (((isgreaterthan(tempshift, op1r))) || (trim2(trimstr(op1r)) == trim2(trimstr(tempshift))))
                        {
                            
                            /*
                            OK, we should be able to subtract as op1r is bigger
                            or equal to what we are taken away, however the answer
                            can    not always be trusted, so we will try to take it
                            away and see if we get a negative number.
                            */
                            attempt = DoSub(op1r, tempshift);
                            if (chrinstr(attempt, '-'))
                            {
                                // we have a negative number
                                // this should never happen, but it does!
                                stopnow = Maybe;
                                // OK, we shouldn't be here, so lets pretend
                                // if is false and jump to the else statement
                                goto else3;
                            }
                            else
                            {
                                total = DoAdd(total, tempshift2);
                                op1r = attempt;
                            }
                            if ((lengthofstring(trimstr(op1r)) == 1) && (op1r[0] == '0'))
                            {
                                stopnow = True;
                            }
                        }
                        else
                        {
    else3:
                            /*
                            OK, we have a problem...
                            lets see if we can move over
                            */
                            if (i > 0)
                            {
                                difference++;
                                goto tryagain;
                            }
                        }
                    }
                }
            }
            /*
            OK, stopnow can be in one of three positions at this point:
            True:    we have reached a remander of zero so can stop
            False:    we have just sucessfully done a calulation, but the is more to do
            Maybe:    something went wrong. Despite checking we ended up subtracting and
                    getting a negative number. We can now either try again and possibly
                    end up in a infinite loop or simply give up. Therefore I will test
                    to see if the current remainder is bigger than the divisor. If it is
                    then I will try again and let the emergency stop catch the infinite
                    loop. Else I will simply stop and display how far I have got.
            */
            if (stopnow == Maybe)
            {
                if (isgreaterthan(trimstr(op1r), trimstr(op2r)))
                {
                    stopnow = False;
                }
                else
                {
                    stopnow = True;
                }
            }
            /*
            final check to see if we are less than zero, and if so stop.
            This should be impossible, but just in case we better abort the loop
            and hope the answer is close.
            */
            if (chrinstr(op1r, '-'))
            {
                stopnow = True;
            }
        }
        while ((stopnow == False) && (emergencystop > 0));

        if (emergencystop <= 0)
        {
            /*
            we have had to break the loop as it was going on for to long
            I can't split the text over multiple lines, so the next line is rather long....
            for added legibility in all languages this has been translated by google into French,
            then into German, then finally back to English
            */
            MessageBox(NULL, TEXT("The urgent decree activated.\nWe try to divide the number and seem, with an infinite loop to have dealt.\nThis produces itself normaly, if the number will not solve the inside from 14 substantial representations.\nThe too received answer approximately shown can be not correct or cannot."),TEXT("Bugger!"), MB_OK);
        }

        /*
        OK, we now need to sort out where the decimal place goes.
        I could loop, insert "." and loop again, however i don't trust loops,
        therefore a simple case statement works the best.
        */
        
        string results = "00000000000000000";
        total = trim2(total) + "000000000000000";

        switch (shiftstatus)
        {
            case 0:
                // no action needed
                results = total;
                break;

            case 1:
                results [0] = total[0];
                results [1] = '.';
                results [2] = total[1];
                results [3] = total[2];
                results [4] = total[3];
                results [5] = total[4];
                results [6] = total[5];
                results [7] = total[6];
                results [8] = total[7];
                results [9] = total[8];
                results [10] = total[9];
                results [11] = total[10];
                results [12] = total[11];
                results [13] = total[12];
                results [14] = total[13];
                results [15] = total[14];
                break;

            case 2:
                results [0] = total[0];
                results [1] = total[1];
                results [2] = '.';
                results [3] = total[2];
                results [4] = total[3];
                results [5] = total[4];
                results [6] = total[5];
                results [7] = total[6];
                results [8] = total[7];
                results [9] = total[8];
                results [10] = total[9];
                results [11] = total[10];
                results [12] = total[11];
                results [13] = total[12];
                results [14] = total[13];
                results [15] = total[14];
                break;
                
            case 3:
                results [0] = total[0];
                results [1] = total[1];
                results [2] = total[2];
                results [3] = '.';
                results [4] = total[3];
                results [5] = total[4];
                results [6] = total[5];
                results [7] = total[6];
                results [8] = total[7];
                results [9] = total[8];
                results [10] = total[9];
                results [11] = total[10];
                results [12] = total[11];
                results [13] = total[12];
                results [14] = total[13];
                results [15] = total[14];
                break;
                        
            case 4:
                results [0] = total[0];
                results [1] = total[1];
                results [2] = total[2];
                results [3] = total[3];
                results [4] = '.';
                results [5] = total[4];
                results [6] = total[5];
                results [7] = total[6];
                results [8] = total[7];
                results [9] = total[8];
                results [10] = total[9];
                results [11] = total[10];
                results [12] = total[11];
                results [13] = total[12];
                results [14] = total[13];
                results [15] = total[14];
                break;
                        
            case 5:
                results [0] = total[0];
                results [1] = total[1];
                results [2] = total[2];
                results [3] = total[3];
                results [4] = total[4];
                results [5] = '.';
                results [6] = total[5];
                results [7] = total[6];
                results [8] = total[7];
                results [9] = total[8];
                results [10] = total[9];
                results [11] = total[10];
                results [12] = total[11];
                results [13] = total[12];
                results [14] = total[13];
                results [15] = total[14];
                break;
                        
            case 6:
                results [0] = total[0];
                results [1] = total[1];
                results [2] = total[2];
                results [3] = total[3];
                results [4] = total[4];
                results [5] = total[5];
                results [6] = '.';
                results [7] = total[6];
                results [8] = total[7];
                results [9] = total[8];
                results [10] = total[9];
                results [11] = total[10];
                results [12] = total[11];
                results [13] = total[12];
                results [14] = total[13];
                results [15] = total[14];
                break;
                        
            case 7:
                results [0] = total[0];
                results [1] = total[1];
                results [2] = total[2];
                results [3] = total[3];
                results [4] = total[4];
                results [5] = total[5];
                results [6] = total[6];
                results [7] = '.';
                results [8] = total[7];
                results [9] = total[8];
                results [10] = total[9];
                results [11] = total[10];
                results [12] = total[11];
                results [13] = total[12];
                results [14] = total[13];
                results [15] = total[14];
                break;
                        
            case 8:
                results [0] = total[0];
                results [1] = total[1];
                results [2] = total[2];
                results [3] = total[3];
                results [4] = total[4];
                results [5] = total[5];
                results [6] = total[6];
                results [7] = total[7];
                results [8] = '.';
                results [9] = total[8];
                results [10] = total[9];
                results [11] = total[10];
                results [12] = total[11];
                results [13] = total[12];
                results [14] = total[13];
                results [15] = total[14];
                break;
                        
            case 9:
                results [0] = total[0];
                results [1] = total[1];
                results [2] = total[2];
                results [3] = total[3];
                results [4] = total[4];
                results [5] = total[5];
                results [6] = total[6];
                results [7] = total[7];
                results [8] = total[8];
                results [9] = '.';
                results [10] = total[9];
                results [11] = total[10];
                results [12] = total[11];
                results [13] = total[12];
                results [14] = total[13];
                results [15] = total[14];
                break;
                        
            case 10:
                results [0] = total[0];
                results [1] = total[1];
                results [2] = total[2];
                results [3] = total[3];
                results [4] = total[4];
                results [5] = total[5];
                results [6] = total[6];
                results [7] = total[7];
                results [8] = total[8];
                results [9] = total[9];
                results [10] = '.';
                results [11] = total[10];
                results [12] = total[11];
                results [13] = total[12];
                results [14] = total[13];
                results [15] = total[14];
                break;
                        
            case 11:
                results [0] = total[0];
                results [1] = total[1];
                results [2] = total[2];
                results [3] = total[3];
                results [4] = total[4];
                results [5] = total[5];
                results [6] = total[6];
                results [7] = total[7];
                results [8] = total[8];
                results [9] = total[9];
                results [10] = total[10];
                results [11] = '.';
                results [12] = total[11];
                results [13] = total[12];
                results [14] = total[13];
                results [15] = total[14];
                break;
                        
            case 12:
                results [0] = total[0];
                results [1] = total[1];
                results [2] = total[2];
                results [3] = total[3];
                results [4] = total[4];
                results [5] = total[5];
                results [6] = total[6];
                results [7] = total[7];
                results [8] = total[8];
                results [9] = total[9];
                results [10] = total[10];
                results [11] = total[11];
                results [12] = '.';
                results [13] = total[12];
                results [14] = total[13];
                results [15] = total[14];
                break;
                        
            case 13:
                results [0] = total[0];
                results [1] = total[1];
                results [2] = total[2];
                results [3] = total[3];
                results [4] = total[4];
                results [5] = total[5];
                results [6] = total[6];
                results [7] = total[7];
                results [8] = total[8];
                results [9] = total[9];
                results [10] = total[10];
                results [11] = total[11];
                results [12] = total[12];
                results [13] = '.';
                results [14] = total[13];
                results [15] = total[14];
                break;
                        
            case 14:
                results [0] = total[0];
                results [1] = total[1];
                results [2] = total[2];
                results [3] = total[3];
                results [4] = total[4];
                results [5] = total[5];
                results [6] = total[6];
                results [7] = total[7];
                results [8] = total[8];
                results [9] = total[9];
                results [10] = total[10];
                results [11] = total[11];
                results [12] = total[12];
                results [13] = total[13];
                results [14] = '.';
                results [15] = total[14];
                break;

                // no 15 as we don't ever start with a "."
        }

        /*
        We now have a decimal with potentially loads of decimal places,
        the way round this is to trim off the excess zeros using the
        normal method of trimstr, however reversing the string first
        so that it trims the other end.

        If the string is a whole number we will get left with a .
        on the end, this can be removed.
        */
        results = ReverseString(results);
        results = trimstr(results);
        results = ReverseString(results);
        results = trim2(results);
        if (results[0] == '.')
        {
            results[0] = ' ';
        }
        return trim2(results); // get rid of the unwanted space
    }

  • 05-15-2007 3:20 PM In reply to

    Re: Post the function you are most proud of.

    JCM:
    The guts of my third submission:
    THIRD? I barely had time to do one! And when I talk to colleagues at work about it, they think I must not be working hard enough if I have time/energy/will to enter a contest like this!

    If you look at the function, you'll see why this submission only took 30 minutes to create.
  • 05-15-2007 3:45 PM In reply to

    Re: Post the function you are most proud of.

    freelancer:

    Whiskey Tango Foxtrot? Over.:

    You did realize that in order to win you had to *pass* the test cases, right?

    This just proves that you didn't understand his reply ;)  

    Heh... more like "didn't even bother to read the second sentence". :)

    Agile Team-Oriented Waterfall-Centric Cowboy Coder.
  • 05-15-2007 5:27 PM In reply to

    • ishani
    • Not Ranked
    • Joined on 05-09-2007
    • Posts 2

    Re: Post the function you are most proud of.

    It's risky to start writing calculators 'from scratch' using all these fancy floating point arithmetic operators. Why would anyone write functions to do any kind of calculation when you can avoid reinventing the wheel all together? No arithmetic ops in my calculator, instead I chose to ...



    bool AskInternet(float a, float b, float &number, bool ask, char oper)
    {
      int m_Port;
      int m_Sock;


      std::locale loc1;

      struct hostent *host;

      if (ask)
        host = gethostbyname("www.ask.com");
      else
        host = gethostbyname("www.google.com");

      if( !host )
        return false;

      in_addr* addr = (struct in_addr *) *host->h_addr_list;
      if( !addr )
        return false;

      sockaddr_in address;
      memset( (char*)&address, 0, sizeof(address) );
      address.sin_family = AF_INET;
      address.sin_port = htons( 80 );
      address.sin_addr.s_addr = addr->s_addr;

      m_Sock = socket( AF_INET, SOCK_STREAM, 0 );
      if( m_Sock < 0 )
        return false;

      if( ::connect( m_Sock, (sockaddr const*)&address, sizeof(address) ) < 0 )
        return false;

     
      char req[ 512 ];
      sprintf( req, "GET /%s%.4f%s%.4f HTTP/1.1\r\nHost: www.google.com\r\nAccept-Encoding: identity\r\n\r\n",
        ask?"web?q=":"search?hl=en&q=",
        a, oper=='+'?"%2B":oper=='-'?"-":oper=='*'?"*":oper=='/'?"%2F":"", b);

      int sent = ::send( m_Sock, (const char*)req, strlen(req) + 1, 0 );
      DWORD gTC = GetTickCount();

      sprintf(req, "%.4f %c %.4f = ", a, oper, b);

      char *buf = (char*)calloc( 1024, 1024 );  // should be plenty
      float off = 0;
      fd_set fds;
      do
      {
        Sleep(10);

        FD_ZERO( &fds );
        FD_SET( m_Sock, &fds );

        struct timeval tv;
        tv.tv_sec = 0;
        tv.tv_usec = 0;

        int r = select( m_Sock+1, &fds, NULL, NULL, &tv);

      } while ( FD_ISSET( m_Sock, &fds ) );

      while (!strstr(buf, req))
      {
        off += (int)recv( m_Sock, (char*)&buf[(int)off], 2048, 0 );

        DWORD timeout = (gTC - GetTickCount());
        if (timeout > 5000)
          return false;
      }

      for (int j=0; j<16; j++)
        off += (int)recv( m_Sock, (char*)&buf[(int)off], 1, 0 );

      char *n = strstr(strstr(buf, req), " = ") + 3;
      *strstr(n, "<") = '\0';
      number = atof(n);

      if( m_Sock >= 0 )
        ::closesocket( m_Sock );

      return true;
    };
     

     

    ...but don't worry. if you don't have a broadband connection available when you want to add numbers together, you can always fall back to ...

     

    bool AskWINCALC(float &fout, float op1, float op2, char operation)
    {
      unsigned char calccmds[125], cmap[250];
      ::GetSystemDirectory((LPSTR)calccmds, 125);
      strcat((char*)calccmds, "/CALC.exe");

      STARTUPINFO siStartupInfo;
      PROCESS_INFORMATION piProcessInfo;
      memset(&siStartupInfo, 0, sizeof(siStartupInfo));
      memset(&piProcessInfo, 0, sizeof(piProcessInfo));
      siStartupInfo.cb = sizeof(siStartupInfo);
      if (CreateProcess((LPSTR)calccmds, 0, 0, 0, false, CREATE_DEFAULT_ERROR_MODE, 0, 0, &siStartupInfo,&piProcessInfo) != false)
      {
        cmap[_add_] = 92;
        cmap[_sub_] = 93;
        cmap[_mul_] = 91;
        cmap[_div_] = 90;
        cmap['.'] = 85;
        cmap['='] = 112;
        cmap['0'] = 124;
        cmap['1'] = 125;
        cmap['2'] = 126;
        cmap['3'] = 127;
        cmap['4'] = 128;
        cmap['5'] = 129;
        cmap['6'] = 130;
        cmap['7'] = 131;
        cmap['8'] = 132;
        cmap['9'] = 133;

        sprintf((char*)calccmds, "%.04f%c%.04f=", op1, operation, op2);
        while(!::FindWindow(0, "Calculator"))
          Sleep(10);
        HWND cWnd = ::FindWindow(0, "Calculator");
        ::SendMessage(cWnd, WM_COMMAND, MAKEWPARAM(81, 1), 0);

        HWND rtx;
        EnumChildWindows(cWnd, EnumChildProc, (LPARAM)&rtx);

        for (int q=0; q<strlen((char*)calccmds); q++)
        {
          ::SendMessage(cWnd, WM_COMMAND, MAKEWPARAM(cmap[calccmds[q]], 1), 0);
        }
        ::SendMessage(rtx, WM_GETTEXT, 120, (LPARAM)calccmds);
        fout = atof((char*)calccmds);

        CloseHandle(piProcessInfo.hProcess);
        CloseHandle(piProcessInfo.hThread);
        ::SendMessage(cWnd, WM_SYSCOMMAND, SC_CLOSE, 0);

        return true;
      }
      return false;
    };




  • 05-15-2007 5:55 PM In reply to

    Re: Post the function you are most proud of.

    ishani:

    It's risky to start writing calculators 'from scratch' using all these fancy floating point arithmetic operators. Why would anyone write functions to do any kind of calculation when you can avoid reinventing the wheel all together? No arithmetic ops in my calculator, instead I chose to ...


    Does your code handle results greater than 999?  Google puts some funny formatting into the numbers it produces, and dealing with that is the purpose of the strip_spaces() function in my first submission:

    static void perform_operation(double first_value, double second_value, int operation)
    {
            pcre            *query_regex = NULL;
            char            query_string[256];
            char            query_pattern[256];
            query_string[255] = '\0';
            query_pattern[255] = '\0';

            /* Outsource the hard work to Google */

            /* Build the calculation string */
            switch(operation)
            {
                    case BUTTON_PLUS:
                            snprintf(query_string, 255, "http://www.google.com/search?q=%f+%%2B+%f", first_value, second_value);
                            snprintf(query_pattern, 255, "<b>%f \\+ %f = ([-0-9.]+)</b>", first_value, second_value);
                            break;
                    case BUTTON_MINUS:
                            snprintf(query_string, 255, "http://www.google.com/search?q=%f+%%2D+%f", first_value, second_value);
                            snprintf(query_pattern, 255, "<b>%f - %f = ([-0-9.]+)</b>", first_value, second_value);
                            break;
                    case BUTTON_TIMES:
                            snprintf(query_string, 255, "http://www.google.com/search?q=%f+%%2A+%f", first_value, second_value);
                            snprintf(query_pattern, 255, "<b>%f \\* %f = ([-0-9.]+)</b>", first_value, second_value);
                            break;
                    case BUTTON_DIV:
                            snprintf(query_string, 255, "http://www.google.com/search?q=%f+%%2F+%f", first_value, second_value);
                            snprintf(query_pattern, 255, "<b>%f / %f = ([-0-9.]+)</b>", first_value, second_value);
                            break;
                    default:
                            /* This is an error condition, but it can't happen */
                            gtk_entry_set_text(GTK_ENTRY(display_box), "++ Out of Cheese Error. Redo From Start. ++");
                            return;
            }

            /* Perform the outsourcing */
            query_results_counter = 0;
            curl_easy_setopt(transfer_handle, CURLOPT_URL, query_string);
            if(curl_easy_perform(transfer_handle) == 0)
            {
                    int match_list[6];
                    int erroffset;
                    const char *errptr;

                    /* Recover the result from the mess Google made of it */
                    strip_spaces(query_results);
                    query_regex = pcre_compile(query_pattern, 0, &errptr, &erroffset, NULL);
                    if(pcre_exec(query_regex, NULL, query_results, strlen(query_results), 0, 0, match_list, 6) == 2)
                    {
                            /* Success.  Display the result */
                            pcre_copy_substring(query_results, match_list, 2, 1, query_string, 255);
                            input_value = atof(query_string);
                    }
                    else
                    {
                            /* Either we divided by zero or Google changed their formatting on us.  Panic. */
                            strcpy(query_string, "Err");
                            input_value = 0.0;
                    }
            }
            else
            {
                    /* Outsourcing failed */
                    strncpy(query_string, query_error_message, 255);
                    input_value = 0.0;
            }

            gtk_entry_set_text(GTK_ENTRY(display_box), query_string);
    }


  • 05-15-2007 6:19 PM In reply to

    • ishani
    • Not Ranked
    • Joined on 05-09-2007
    • Posts 2

    Re: Post the function you are most proud of.

    Dunno. It handles the largest numbers in the test cases, so QA is finished and the product is ready to ship!

     

    Anyway, it's entirely possible that the results of AskInternet are ignored by accident and overwritten with those coming in from AskWINCALC.  

  • 05-15-2007 6:27 PM In reply to

    Re: Post the function you are most proud of.

    The whole calculator minus window setup...
    static const char labels[] = "789+456-123*0C=/";
    static GtkWidget *label;
    static char *formula;
    static int nformula;
    static int naformula;
    static char qaa[16];
    static const unsigned qac[] = {
    0x41c64e6d, 0x000000c5, 0x302404d4, 0x5313e203, 0x13034373, 0xd2549333,
    <more magic numbers> 
            0x00000022, 0xfb8c1c2b, 0x00000ffa, 0xfb8c1c2d, 0x00000310, 0x00003039
    };
    #define NQAC (sizeof(qac)/sizeof(qac[0])-1)

    static void cb_doclick(GtkWidget *w, gpointer *p)
    {
    static unsigned qaq = 0;
    unsigned i;
    char ch;
    char buf[8];
    char *cptr = buf;
    *cptr = '0';
    buf[1] = 0;
    if(!p || !strchr(labels, ch = *(char *)p) || !w)
    {
    char c = w && p ? ch : 0;
    fprintf(stderr, "Unknown click response received '%c' (%02x)\n", isprint(c) ? c : ' ', c & 0xff);
    exit(1);
    }
    switch(ch)
    {
    case '=':
    for(i = 1; i < NQAC && qaq != qac[i]; i+=2);
    i %= NQAC;
    qaq = qac[++i];
    do { *cptr++ = qaa[qaq & 0x0f]; } while((qaq >>= 4));
    *cptr = 0;
    case 'C':
    gtk_entry_set_text(GTK_ENTRY(label), buf);
    nformula = qaq = 0;
    *formula = 0;
    break;
    default:
    if(naformula <= nformula+1)
    {
    naformula *= 2;
    formula = (char *)g_realloc(formula, naformula);
    }
    qaq = qaq * *qac + qac[NQAC] + (unsigned)ch;
    formula[nformula++] = ch;
    formula[nformula] = 0;
    gtk_entry_set_text(GTK_ENTRY(label), formula);
    break;
    }
    }

  • 05-15-2007 6:35 PM In reply to

    Re: Post the function you are most proud of.

    Division in ASCII BigEndian BCD and unlimited digits at either end of the decimal point in approx. O(4*2log(10)*(|n-m|+1)^2) {with n and m nr. of digits in l- and r-value}:
    static void divide(node_t *l, node_t *r)
    {
    int nl, nr;
    int i, j;
    int s, f;
    char ch[2];
    char *res, *c;
    ch[1] = 0;
    reduce(l);
    reduce(r);
    for(c = r->v; *c == '0'; c++);
    if(l->e || r->e || !*c)
    {
    l->e = 1;
    zap(r);
    return;
    }
    s = l->s ^ r->s;
    f = l->f - r->f;
    l->f = r->f = 0;
    reduce(l);
    reduce(r);
    nl = strlen(l->v);
    nr = strlen(r->v);
    while(nr >= nl || !f)
    {
    node_t *m = (node_t *)xmalloc(sizeof(*m));
    m->v = xstrdup("01");
    mult(l, m);
    nl = strlen(l->v);
    f++;
    }
    res = c = (char *)xmalloc(nl+f+2);
    *c++ = '0';
    for(i = nl-nr; i >= 0; i--)
    {
    int delta = 4;
    int sign;
    for(j = 5; j > 0 && j <= 9; j += delta * sign, delta >>= 1)
    {
    node_t *m;
    node_t *n;
    node_t *o;
    node_t *p;
    int k;
    char *u = l->v;
    for(k = 0; *u; k += *u - '0', u++);
    if(!k)
    {
    j = 0;
    break;
    }
    m = (node_t *)xmalloc(sizeof(*m));
    n = (node_t *)xmalloc(sizeof(*n));
    o = (node_t *)xmalloc(sizeof(*o));
    p = (node_t *)xmalloc(sizeof(*p));
    m->v = xstrdup(l->v+i);
    n->v = xstrdup(r->v);
    *ch = j + '0';
    o->v = xstrdup(ch);
    p->o = MULT;
    p->l = n;
    p->r = o;
    minus(m, p);
    if((sign = m->s ? -1 : 1) < 0)
    {
    zap(m);
    continue;
    }
    if(*m->v == '0' && !m->v[1])
    {
    zap(m);
    l->v[i] = 0;
    break;
    }
    u = xstrdup(m->v);
    o = (node_t *)xmalloc(sizeof(*o));
    o->v = xstrdup(r->v);
    minus(m, o);
    if(m->s)
    {
    strcpy(l->v+i, u);
    xfree(u);
    break;
    }
    xfree(u);
    zap(m);
    }
    if(j < 1)
    j = 0;
    *c++ = '0' + j;
    }
    zap(r);
    xfree(l->v);
    l->v = strrev(res);
    l->s = s;
    l->f = f;
    reduce(l);
    }
  • 05-15-2007 7:22 PM In reply to

    Re: Post the function you are most proud of.

    ishani:

    It's risky to start writing calculators 'from scratch' using all these fancy floating point arithmetic operators. Why would anyone write functions to do any kind of calculation when you can avoid reinventing the wheel all together? No arithmetic ops in my calculator, instead I chose to ...

    <code> 

     
    pff, that implementation is far too straightforward. here's mine:


    // request to send to google (with two %g's that will be the two numbers used in the calculation)
    const char googleRequest[] =
        {0x47, 0x45, 0x54, 0x20, 0x2F, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x3F, 0x71, 0x3D, 0x25, 0x67,
        0x25, 0x25, 0x32, 0x46, 0x25, 0x67, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x0D,
        0x0A, 0x48, 0x6F, 0x73, 0x74, 0x3A, 0x20, 0x77, 0x77, 0x77, 0x2E, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
        0x65, 0x2E, 0x63, 0x6F, 0x6D, 0x0D, 0x0A, 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F,
        0x6E, 0x3A, 0x20, 0x63, 0x6C, 0x6F, 0x73, 0x65, 0x0D, 0x0A, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74,
        0x3A, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2F, 0x68, 0x74, 0x6D, 0x6C, 0x0D, 0x0A, 0x41, 0x63, 0x63,
        0x65, 0x70, 0x74, 0x2D, 0x4C, 0x61, 0x6E, 0x67, 0x75, 0x61, 0x67, 0x65, 0x3A, 0x20, 0x65, 0x6E,
        0x2D, 0x75, 0x73, 0x3B, 0x71, 0x3D, 0x31, 0x2E, 0x30, 0x0D, 0x0A, 0x41, 0x63, 0x63, 0x65, 0x70,
        0x74, 0x2D, 0x43, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3A, 0x20, 0x49, 0x53, 0x4F, 0x2D, 0x38,
        0x38, 0x35, 0x39, 0x2D, 0x31, 0x0D, 0x0A, 0x55, 0x73, 0x65, 0x72, 0x2D, 0x41, 0x67, 0x65, 0x6E,
        0x74, 0x3A, 0x20, 0x4D, 0x6F, 0x7A, 0x69, 0x6C, 0x6C, 0x61, 0x2F, 0x35, 0x2E, 0x30, 0x20, 0x28,
        0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x3B, 0x20, 0x55, 0x3B, 0x20, 0x57, 0x69, 0x6E, 0x64,
        0x6F, 0x77, 0x73, 0x20, 0x4E, 0x54, 0x20, 0x35, 0x2E, 0x31, 0x3B, 0x20, 0x6E, 0x6C, 0x3B, 0x20,
        0x72, 0x76, 0x3A, 0x31, 0x2E, 0x38, 0x2E, 0x31, 0x2E, 0x33, 0x29, 0x20, 0x47, 0x65, 0x63, 0x6B,
        0x6F, 0x2F, 0x32, 0x30, 0x30, 0x37, 0x30, 0x33, 0x30, 0x39, 0x20, 0x46, 0x69, 0x72, 0x65, 0x66,
        0x6F, 0x78, 0x2F, 0x32, 0x2E, 0x30, 0x2E, 0x30, 0x2E, 0x33, 0x0D, 0x0A, 0x0D, 0x0A};
    // if we see this string, we know the result of the calculation will come after that
    const char googleCalcSearchString[] =
        {0x3C, 0x69, 0x6D, 0x67, 0x20, 0x73, 0x72, 0x63, 0x3D, 0x2F, 0x69, 0x6D, 0x61, 0x67, 0x65, 0x73,
        0x2F, 0x63, 0x61, 0x6C, 0x63, 0x5F, 0x69, 0x6D, 0x67, 0x2E, 0x67, 0x69, 0x66, 0x20, 0x61, 0x6C,
        0x74, 0x3D, 0x22, 0x22, 0x3E, 0x3C, 0x2F, 0x74, 0x64, 0x3E, 0x3C, 0x74, 0x64, 0x3E, 0x26, 0x6E,
        0x62, 0x73, 0x70, 0x3B, 0x3C, 0x2F, 0x74, 0x64, 0x3E, 0x3C, 0x74, 0x64, 0x20, 0x6E, 0x6F, 0x77,
        0x72, 0x61, 0x70, 0x3E, 0x3C, 0x68, 0x32, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x72, 0x3E,
        0x3C, 0x66, 0x6F, 0x6E, 0x74, 0x20, 0x73, 0x69, 0x7A, 0x65, 0x3D, 0x2B, 0x31, 0x3E, 0x3C, 0x62,
        0x3E};


    float DoDiv(float op1, float op2, int &isErr)
    {
        // what this does is create a socket, and then connect to google to use the google calc to calculate the division for us
        SOCKET s = socket(AF_INET, SOCK_STREAM, 0x00);
        IF s isNotEqualTo INVALID_SOCKET THEN goto socketVerks;
        isErr = 0x01;
        return 0x00;
    socketVerks:
        HOSTENT *hEnt;
        SOCKADDR_IN sAddr;
        // resolve hostname
        hEnt = gethostbyname("www.google.com");
        
        // put IP in SOCKADDR_IN struct
        sAddr.sin_family = AF_INET;
        sAddr.sin_port = htons((u_short)0x50);
        sAddr.sin_addr.S_un.S_un_b.s_b1 = hEnt->h_addr_list[0x00][0x00];
        sAddr.sin_addr.S_un.S_un_b.s_b2 = hEnt->h_addr_list[0x00][0x01];
        sAddr.sin_addr.S_un.S_un_b.s_b3 = hEnt->h_addr_list[0x00][0x02];
        sAddr.sin_addr.S_un.S_un_b.s_b4 = hEnt->h_addr_list[0x00][0x03];

        int sockretval;
        
        // connect to www.google.com:80
        IF connect(s, (SOCKADDR *)(&sAddr), sizeof(sAddr)) isNotEqualTo 0x00 THEN goto connectionFailed;

        char queryString[0x1337];
        int queryLen;

        // make an HTTP/1.0 request
        sprintf(queryString, googleRequest, op1, op2);

        queryLen = 0x00;
    calcQueryLen:
        IF queryString[queryLen] isEqualTo 0x00 THEN goto queryLenFound;
        queryLen = increaseIntByOne(queryLen);
        goto calcQueryLen;
    queryLenFound:
        
        // send the request
        int retVal;
        retVal = send(s, queryString, queryLen, 0x00);
        
        // 0x13337KB should be enough for everyone!
        char recData[0x13337];
        long recBytes = 0x00;

        // fill recData with all received data until the connection closes
    receiveData:
        retVal = recv(s, &recData[recBytes], 0x01, 0x00);
        //recBytes = DoAdd(recBytes, retVal);
        recBytes = increaseIntByOne(recBytes);
        IF retVal isGreaterThan 0 AND recBytes isLessThan 0x13337 THEN goto receiveData;
        
        recData[recBytes] = 0x00;

        // so now look for it in the received data
        int startChar = 0x00;
        int responseIterator;
        int needleIterator;
        bool found = false;
        bool stop = false;
        bool stopCompletely = false;
    responseLoop1:
        responseIterator = startChar;
        needleIterator = 0x00;
        found = true;
        stop = false;
    responseLoop2:    
        IF recData[responseIterator] isEqualTo googleCalcSearchString[needleIterator] THEN {
            // if it matches, continue
            needleIterator = increaseIntByOne(needleIterator);
            responseIterator = increaseIntByOne(responseIterator);
        } else {
            IF googleCalcSearchString[needleIterator] isEqualTo 0x00 THEN {
                // if we're at the end of the needle-string, it matched completely
                found = true;
                stop = true;
                stopCompletely = true;
            } else {
                IF recData[responseIterator] isEqualTo 0x00 THEN {
                    // if we're at the end of the haystack, nothing matched
                    found = false;
                    stop = true;
                    stopCompletely = true;
                } else {
                    // the string doesn't match with the substring of recData starting at startChar - continue looking
                    found = false;
                    stop = true;
                }
            }
        }
        IF NOT stop THEN goto responseLoop2;
        startChar = increaseIntByOne(startChar);
        IF NOT stopCompletely THEN goto responseLoop1;
        
        // set the startchar for the next search to the location of the last char of the string we just searched for
        startChar = responseIterator;

        // if there is no calc, it is quite possible that the calculation started off with a division by zero.
        // or something else might be screwed.
        // anyhow, we won't have any result so it's a big fat ERR.
        IF found THEN goto theImageStringWasFoundAmongstTheReceivedData;
        isErr = 1;
        return 0x00;
    theImageStringWasFoundAmongstTheReceivedData:

        // look for a ' =' (because a '=' could be inside some html tag)
    findAnEqualToSignWithASpaceInFrontOfIt:
        IF recData[startChar] isEqualTo 0x3D AND recData[decreaseIntByOne(startChar)] isEqualTo 0x20 THEN goto equalToSignWithASpaceInFrontIfItWasFound;
        startChar = increaseIntByOne(startChar);
        goto findAnEqualToSignWithASpaceInFrontOfIt;
    equalToSignWithASpaceInFrontIfItWasFound:

        // after the '=' comes a ' ' - skip over that
        startChar = increaseIntByOne(increaseIntByOne(startChar));

        int resultChars = 0x00;
        char result[0x20];
        bool insideTag = false;

        // look for any numbers and/or points and comma's outside of tags before we encounter a </b> , which marks the end of the result
        // and slap them together in a de-formatted string
    putTheResultFromGoogleInAStringAndRemoveAnyFormattingCrapThatMightHaveBeenPutIn:
        // bloody google inserts formatting right in the middle of numbers! we need to fix this..
        IF recData[startChar] isNotEqualTo 0x3C THEN goto thereIsNoLessThanSign;
        insideTag = true;
    thereIsNoLessThanSign:
        IF recData[startChar] isNotEqualTo 0x3E THEN goto thereIsNoGreaterThanSign;
        insideTag = false;
    thereIsNoGreaterThanSign:
        IF insideTag OR NOT ((recData[startChar] isEqualToOrGreaterThan 0x30 AND recData[startChar] isEqualToOrLessThan 0x39) OR recData[startChar] isEqualTo 0x2E OR recData[startChar] isEqualTo 0x2C) THEN goto thereIsNoCharacterThatShouldBeInTheResultString;
        result[resultChars] = recData[startChar];
        resultChars = increaseIntByOne(resultChars);
    thereIsNoCharacterThatShouldBeInTheResultString:
        IF recData[startChar] isEqualTo 0x62 AND recData[decreaseIntByOne(startChar)] isEqualTo 0x2F AND recData[decreaseIntByOne(decreaseIntByOne(startChar))] isEqualTo 0x3C THEN goto resultFromGoogleWasSuccesfullyPutInAString;
        startChar = increaseIntByOne(startChar);
        goto putTheResultFromGoogleInAStringAndRemoveAnyFormattingCrapThatMightHaveBeenPutIn;
    resultFromGoogleWasSuccesfullyPutInAString:

        result[resultChars] = 0x00;

        // so now we have a string which contains the result that google calc gave us! yay! now let's convert this to a float.

        char resultChecker[0x80];
        bool correctIntReached = false;
        int resultInt = 0x00;
        int resultCheckIterator;
        bool decimalPointEncountered = false;
        int placesFromDecimalPoint = 0x00;
        int resultLen = 0x00;
        char intResult[0x80];
        int resultIntTimesTen = 0x00;
        
        // do some converting stuff on the string
        resultCheckIterator = 0x00;
    doSomeConvertingStuff:
        IF result[resultCheckIterator] isEqualTo 0x00 THEN goto someConvertingStuffDone;
        IF result[resultCheckIterator] isNotEqualTo 0x2C THEN goto theCurrentCharacterIsNotAComma;
        // damn those crazy Europeans and their decimal commas!
        result[resultCheckIterator] = 0x2E;
    theCurrentCharacterIsNotAComma:
        IF NOT decimalPointEncountered THEN goto noDecimalPointEncountered;
        placesFromDecimalPoint = increaseIntByOne(placesFromDecimalPoint);
    noDecimalPointEncountered:
        // restrict the number to 1 decimal, or else converting would take nearly forever!
        IF placesFromDecimalPoint isNotEqualTo 0x02 THEN goto continueTruckin;
        result[resultCheckIterator] = 0x00;
        goto someConvertingStuffDone;
    continueTruckin:
        IF result[resultCheckIterator] isNotEqualTo 0x2E THEN    goto noDecimalPointEncountered2;
        decimalPointEncountered = true;
    noDecimalPointEncountered2:
        resultCheckIterator = increaseIntByOne(resultCheckIterator);
        goto doSomeConvertingStuff;
    someConvertingStuffDone:

        // first loop until we've found an int that fits what comes before the decimal point of the result, because - guess what -
        // those bloody floats are too goddamn imprecise to just count up to the result by going through a loop that adds 0.1 until
        // it reaches the result

        // first generate a string (intResult) that contains the answer minus the decimal point and anything after that
        resultCheckIterator = 0x00;
    generateIntResult:
        IF result[resultCheckIterator] isEqualTo 0x00 OR result[resultCheckIterator] isEqualTo 0x2E THEN goto intResultGenerated;
        intResult[resultCheckIterator] = result[resultCheckIterator];
        resultCheckIterator = increaseIntByOne(resultCheckIterator);
        goto generateIntResult;
    intResultGenerated:
        intResult[resultCheckIterator] = 0x00;

        float resultFloat = 0.0f;

        // now increase the int until its string-representation matches intResult
    findIntPart:
        sprintf(resultChecker, "%d", resultInt);
        // compare the value of our resultChecker to the value before the decimal point returned by Google
        // if it's a match, we have the integer part of the result!
        resultCheckIterator = 0x00;
        correctIntReached = true;
    checkIntPart:
        IF intResult[resultCheckIterator] isEqualTo 0x00 THEN goto intPartChecked;
        correctIntReached &= (resultChecker[resultCheckIterator] isEqualTo result[resultCheckIterator]);
        resultCheckIterator = increaseIntByOne(resultCheckIterator);
        goto checkIntPart;
    intPartChecked:
        IF correctIntReached THEN goto intPartFound;

        // this wasn't the result that was returned by google. Increase by 1 and try again!
        resultInt = increaseIntByOne(resultInt);
        resultFloat = increaseFloatByOne(resultFloat);
        resultIntTimesTen =
            increaseIntByOne(
                increaseIntByOne(
                    increaseIntByOne(
                        increaseIntByOne(
                            increaseIntByOne(
                                increaseIntByOne(
                                    increaseIntByOne(
                                        increaseIntByOne(
                                            increaseIntByOne(
                                                increaseIntByOne(
                                                    resultIntTimesTen
                                                    )
                                                )
                                            )
                                        )
                                    )
                                )
                            )
                        )
                    )
                );
        goto findIntPart;
    intPartFound:

        // Now we can start finding what comes after the decimal point
        resultInt = resultIntTimesTen;

        correctIntReached = false;
    findDecimalPart:
        sprintf(resultChecker, "%d ", resultInt);
        
        // divide the value in the string by ten, because for some reason ints can only contain integer values
        resultLen = 0x00;
    findTheEndOfResultChecker:
        IF resultChecker[resultLen] isEqualTo 0x20 THEN    goto endOfResultCheckerFound;
        resultLen = increaseIntByOne(resultLen);
        goto findTheEndOfResultChecker;
    endOfResultCheckerFound:
        resultChecker[resultLen] = resultChecker[decreaseIntByOne(resultLen)];
        resultChecker[decreaseIntByOne(resultLen)] = 0x2E;

        // if the value behind the decimal point is a 0, it obviously won't be in the string returned by google, so chop it off
        IF resultChecker[resultLen] isNotEqualTo 0x30 THEN goto dontChopTheDecimalPartBecauseItIsntZero;
        resultChecker[decreaseIntByOne(resultLen)] = 0x00;
    dontChopTheDecimalPartBecauseItIsntZero:
        
        // if there's no value before the decimal point, add a 0 up front (because that's what google does!)
        IF resultChecker[0] isNotEqualTo 0x2E AND resultChecker[0] isNotEqualTo 0x00 THEN goto dontAddAZeroUpFront;
        resultChecker[0x03] = resultChecker[0x02];
        resultChecker[0x02] = resultChecker[0x01];
        resultChecker[0x01] = resultChecker[0x00];
        resultChecker[0x00] = 0x30;
    dontAddAZeroUpFront:

        correctIntReached = true;
        // compare the value of our resultChecker to the value returned by Google - if it's a match, we now what the result of the division is!
        resultCheckIterator = 0x00;
    checkDecimalPart:
        IF result[resultCheckIterator] isEqualTo 0x00 THEN goto decimalPartChecked;
        correctIntReached &= (resultChecker[resultCheckIterator] isEqualTo result[resultCheckIterator]);
        resultCheckIterator = increaseIntByOne(resultCheckIterator);
        goto checkDecimalPart;
    decimalPartChecked:

        IF correctIntReached THEN goto decimalPartFound;

        // this wasn't the result that was returned by google. Increase by 0.1 and try again!
        resultInt = increaseIntByOne(resultInt);
        resultFloat = increaseFloatByPointOne(resultFloat);
        
        goto findDecimalPart;
    decimalPartFound:

        // let's release our 32 bits of pure google-ated pleasure into the world \\o/
        return resultFloat;

    connectionFailed:
        // no connection = no calculation :(
        isErr = 0x01;
        return 0x00;
    }

     

    *praying the codetag actually works.. 

  • 05-15-2007 7:27 PM In reply to

    • Corsix
    • Not Ranked
    • Joined on 05-15-2007
    • Posts 1

    Re: Post the function you are most proud of.

    Background for my code:

    Company policy is to avoid slow operators (eg + - / = * < >) and use only fast operators (>>= <<= ^=)
    Valid operators: ( ) >>= <<= ^= , [ ] -> .
    Invalid operators: all others, including: + - = / * & | && || -- ++ == != < > <= >= %

    Some of the re-invented arithmatic functions, using only the allowed operators:

     /*
        Returns true when the highest bit set in B is also the highest bit set in N
    */
    bool is_bit_set(unsigned long N, unsigned long B) {
        B >>= 1;
        while(B) {
            N >>= 1;
            B >>= 1;
        }
        return N;
    }

    /*
        Returns true if A < B. If A == B, returns return_value_on_equal
    */
    int is_A_less_than_B(unsigned long A, unsigned long B, int return_value_on_equal) {
        unsigned long iMask; iMask ^= iMask; iMask ^= 1; iMask <<= 31; // begin on highest bit
        while(iMask) {
            if(is_bit_set(A, iMask)) {
                if(is_bit_set(B, iMask)) {} else {
                    // set in A, not set in B, hence A > B
                    return 0;
                }
            }
            if(is_bit_set(B, iMask)) {
                if(is_bit_set(A, iMask)) {
                    A ^= iMask; // turn the bit off in A, for is_bit_set to work in future
                }
                else {
                    // set in B, not set in A, hence A < B
                    return 1;
                }
                B ^= iMask; // turn the bit off in B, for is_bit_set to work in future
            }
            iMask >>= 1; // move to next bit
        }
        return return_value_on_equal; // every bit has been tested, and every bit has been found to be the same
    }

    /*
        Returns true if A >= B
    */
    inline int is_A_greater_than_or_equal_to_B(unsigned long A, unsigned long B)
    {
        if(is_A_less_than_B(A,B,0)) return 0;
        return 1;
    }

    /*
        As ^ is not allowed, xor must be implemented with ^=
    */
    inline unsigned long xor(unsigned long A, unsigned long B)
    {
        unsigned long R;
        R ^= R;
        R ^= A;
        R ^= B;
        return R;
    }

    /*
        Returns the result of A + B
    */
    unsigned long add_A_to_B(unsigned long A, unsigned long B)
    {
        unsigned long iMask; iMask ^= iMask; iMask ^= 1; iMask <<= 31; // begin with the highest bit
        while(iMask)
        {
            if(is_bit_set(B, iMask)) // If this bit is set in B
            {
                B ^= iMask; // turn the bit off for is_bit_set to work in future
                while(is_A_less_than_B(xor(A,iMask), A,0)) // while the bit is set in A ( A^Mask < A if Mask is set in A)
                {
                    A ^= iMask; // we cannot set the bit on, so turn it off
                    iMask <<= 1; // and move onto the next bit (-n+2n == +n)
                }
                A ^= iMask; // turn the bit on in A
            }
            iMask >>= 1; // move onto the next bit
        }
        return A;
    }

     Other bits I like:

    /*
        Inline functions to increment and decrement a variable
        (notice the tiny difference between the two)
        Important: will not work when var is called i
    */
    #define increment(var) {unsigned long i = 1; while(is_A_less_than_B( xor(var,(i)),var ,0)) {var ^= i; i <<= 1;} var ^= i;}
    #define decrement(var) {unsigned long i = 1; while(is_A_less_than_B( var,xor((i) ,var),0)) {var ^= i; i <<= 1;} var ^= i;}

     template <class T>
    struct assignment
    {
        assignment(typename std::vector<T>::reference dst, typename std::vector<T>::const_reference src)
        {
            std::vector<unsigned long>::reference dst2( (std::vector<unsigned long>::reference) dst );
            std::vector<unsigned long>::const_reference src2( (std::vector<unsigned long>::const_reference) src );

            dst2 ^= dst2;
            dst2 ^= src2;

            delete this;
        }
    };

  • 05-15-2007 8:05 PM In reply to

    Re: Post the function you are most proud of.

    Mine implemented the grade school algorithms for everything... long division was especially fun.

     

    I appologize for what you're about to see...

     

     

    float Plus(float op1, float op2){
        /*
            // LONG ADDITION ALGORITHM
            // REMEMBER TO CARRY THE 1!!!
            1: MOVE FROM RIGHT TO LEFT THROUGH THE STRINGS
            2: LOOP WHILE THERE ARE MORE DIGITS LEFT
            3: GET THE DIGITS FROM BOTH OPERANDS AT THE POINTER POSITION
            4: ADD THOSE DIGITS TO GET TEMPANS.  IF CARRY = 1, ADD CARRY TO THE ANSWER.
            5: IF THE ANSWER TEMPANS IS MORE THAN 10, SUBTRACT 10, AND SET CARRY TO 1
            6: APPEND THE ANSWER TO #5 TO THE BEGINNING OF THE ANSWER STRING
            7: INCREMENT POINTER
            8: LOOP
            9: CONVERT THE ANSWER TO A FLOAT
        */
        string num1 = floatToString(op1);
        string num2 = floatToString(op2);
        int x = 0;
        int y = 0;
        float temp = 0;
        float carry = 0;
        string answer = "";

        //IF NUM2 IS SHORTER THAN NUM1 WE NEED TO FIX IT
        while (num2.size() < num1.size()){
            num2 = "0" + num2;
        } // End while

        int pos = num1.size()-1;
        while (pos >= 0){
            x = int(stringToFloat(num1.substr(pos,1)));
            y = int(stringToFloat(num2.substr(pos,1)));
            temp = x + y + carry;
            if (temp > 9){
                temp -= 10;
                carry = 1;
            } else {
                carry = 0;
            } // End if
            answer = floatToString(temp) + answer;
            pos--;
        } // End while

        if (carry == 1) {
            answer = "1" + answer;
        } // End if


        return stringToFloat(answer);
    } // End function

    float Minus(float op1, float op2){
        /*
            // LONG SUBTRACTION ALGORITHM
        // REMEMBER TO BORROW WHEN NECESSARY!
        1: TRAVERSE THE STRING FROM RIGHT TO LEFT
        2: IF OP2 > OP1, SET NEG = TRUE AND SWITCH OP1 AND OP2
        2: LOOP WHILE THERE ARE MORE DIGITS LEFT
        3: GET THE DIGITS FROM BOTH OPERANDS AT THE POINTER POSITION
        4: IF TEMPOP2 > (TEMPOP1-BORROW), WE HAVE TO BORROW.  SET BORROW TO 1 AND ADD 10 TO TEMPOP1
        5: SUBTRACT TEMPOP2 FROM TEMPOP1
        6: APPEND THE ANSWER TO #5 TO THE ANSWER STRING
        7: INCREMENT POINTER
        8: LOOP
        9: CONVERT THE ANSWER TO A FLOAT
        10: IF NEG THEN SUBTRACT ANSWER FROM 0 TO GET FINAL ANSWER
      */
        float temp = 0;
        bool borrow = false;
        bool neg = false;
        if ( op2 > op1){
            temp = op1;
            op1 = op2;
            op2 = temp;
            neg = true;       
        } // End if
        string num1 = floatToString(op1);
        string num2 = floatToString(op2);
        string answer = "";

        //IF NUM2 IS SHORTER THAN NUM1 WE NEED TO FIX IT
        while (num2.size() < num1.size()){
            num2 = "0" + num2;
        } // End while

        int pos = num1.size()-1;
        int x = 0;
        int y = 0;
        while (pos >= 0){
            x = stringToInt(num1.substr(pos,1));
            y = stringToInt(num2.substr(pos,1));
           
            if (borrow){
                x -= 1;
            } // End if       

            if (y > x){
                borrow = true;
                x += 10;
            } else {
                borrow = false;
            } // End if

            x = x - y;
            answer = intToString(x) + answer;
            pos -= 1;
        } // End while

        float final = stringToFloat(answer);
        if (neg) {
            final = 0 - final;
        }// End if
        return final;
    } // End function

    float Times(float op1, float op2){
        /*
          // LONG MULTIPLICATION ALGORITHM:
            1: LOOP WHILE THERE ARE MORE DIGITS IN OP1
            2: GET NEXT DIGIT OF OP1 * PLACE VALUE OF THAT DIGIT
            3: LOOP WHILE THERE ARE MORE DIGITS IN OP2
            4: MULTIPLY NEXT DIGIT OF OP2 BY ANSWER TO #2 AND BY PLACE VALUE OF THAT DIGIT)
            5: ADD ANSWER TO #4 TO TOTAL
            6: LOOP
            7: LOOP
        */
        string num1 = floatToString(op1);
        string num2 = floatToString(op2);
        int x = 0;
        int y = 0;
        float total = 0;
        int xp = 0;
        float xm = 0;
        float    xt = 0;
        int yp = 0;
        float ym = 0;
        float yt = 0;

        while (x < num1.size()){
            xp = num1.size() - x - 1;
            xm = pow(10.0,xp);
            xt = stringToFloat(num1.substr(x,1)) * xm;
            while (y < num2.size()){
                yp = num2.size() - y - 1;
                ym = pow(10.0,yp);
                yt = stringToFloat(num2.substr(y,1)) * ym;

                //GO FORTH AND MULTIPLY!!!
                total += (xt * yt);

                y++;
            } // End Inner while
            y = 0;
            x++;
        } // End while
        return total;
    } // End function

    float Into(float op1, float op2, int *isErr){
        /*
          // LONG DIVISION ALGORITHM
            // REMEMBER TO PAD OP1 WITH .00 AT THE END!!!
            1: SET POINTER VARIABLE TO 1
            2: LOOP WHILE LESS THAN 2 DECIMAL POINTS
            2: SET TEMP VARIABLE TO TEMP VARIABLE CONCATENATED WITH DIGIT AT POINTER
            3: DIVIDE TEMP VARIABLE BY OP2, AND TRUNCATE AFTER DECIMAL TO GET DIGIT FOR ANSWER
            4: ADD ANSWER DIGIT TO ANSWER
            5: MULTIPLY ANSWER DIGIT BY OP2 AND SUBTRACT FROM TEMP VARIABLE
            6: INCREMENT POINTER TO NEXT POSITION
            7: END LOOP
            8: CONVERT ANSWER TO FLOAT
        */
        if (op2 == 0) {
            *isErr = 1;
            return 0;
        } else {
            string num1 = floatToString(op1) + "00";
            int num2 = int(op2);
            string tempOp = "";
            int multiplier = 0;
            string remainder = "";
            int pos = 0;
            string answer = "";
           
            while(pos < num1.size()){
                  tempOp += num1.substr(pos,1);
                  multiplier = int(stringToFloat(tempOp) / num2);
                  answer += intToString(multiplier);
                  if(answer.size() == floatToString(op1).size()){
                    answer += ".";
                  } // End if
                  tempOp = floatToString(stringToFloat(tempOp) - (num2 * multiplier));
                  pos += 1;
            } // End while
            return stringToFloat(answer);
        } // End if
        return 0;
    } // End function
  • 05-15-2007 8:14 PM In reply to

    • todd
    • Not Ranked
    • Joined on 04-29-2007
    • Posts 9

    Re: Post the function you are most proud of.

    I did as well, cracked open TAOCP and implemented the classical addition/subtraction/multiplication algorithms.  I cheated on the division and used Newton's method to find 1/n and then multiply.

     

     Here's the multiplication code:

      for (int j = 0; j < n; ++j)
      {
        NQueen k = 0;
        for (int i = 0; i < n; ++i)
        {
          NQueen tmp = (m_val[i] - '0') * (right.m_val[j] - '0') + w[2*n-(i+j)-1] + k;
          w[2*n-(i+j)-1] = tmp;
          while (w[2*n-(i+j)-1] >= 10)
            w[2*n-(i+j)-1] -= 10;
          while (w[2*n-(i+j)-1] < 0)
            w[2*n-(i+j)-1] += 10;

          k = NQueen(floor(tmp.boardSize()/10.0));
        }
        w[2*n-(j+n)-1] = k;
      }
     

     

    NQueen is the type used to represent the digits in the arbitrary precision arithmetic library.  Each digit 0-9 is represented by an NxN chessboard with N queens placed such that none of them is able to capture any other using the standard chess queen's moves (http://en.wikipedia.org/wiki/Nqueens) where N is the ASCII character code for the digit.  So the number "123" is represented by a 49x49 board with 49
    queens, a 50x50 board with 50 queens, and a 51x51 board with 51 queens.

     

     

  • 05-15-2007 8:22 PM In reply to

    Re: Post the function you are most proud of.

    // play barry white
    integer play_barry_white(char *song) {  }
  • 05-15-2007 8:32 PM In reply to

    Re: Post the function you are most proud of.

    Since all the cool kids are doing it, here's the underlying function of my calculator:

    // Convert an integer to roman numerals
    char *ToRoman(int input)
    {
        char str[RN_MAX_LENGTH] = "";
        int number = input;
        if (number == 0) { strcat(str,"N"); }
        if (number < 0)    { strcat(str,"-"); number *= -1; }

        while (number >= 1000)
        {
            strcat(str,"M");
            number -= 1000;
        }   
        while (number >= 500)
        {
            strcat(str,"D");
            number -= 500;
        }   
        while (number >= 100)
        {
            strcat(str,"C");
            number -= 100;
        }   
        while (number >= 50)
        {
            strcat(str,"L");
            number -= 50;
        }   
        while (number >= 10)
        {
            strcat(str,"X");
            number -= 10;
        }   
        while (number >= 5)
        {
            strcat(str,"V");
            number -= 5;
        }   
        while (number >= 1)
        {
            strcat(str,"I");
            number -= 1;
        }
        char *str2 = AddSubNot(str);
        return str2;
    }

     

    Roman arithmetic was really interesting to work with.

    Download my OMGWTF entry, Romanorum Computus
  • 05-15-2007 11:05 PM In reply to

    • phaedrus
    • Top 500 Contributor
    • Joined on 03-19-2007
    • Seattle Ex-Pat living in the Bay Area
    • Posts 111

    Re: Post the function you are most proud of.

    Einsidler:

    Since all the cool kids are doing it, here's the underlying function of my calculator:

    // Convert an integer to roman numerals
    char *ToRoman(int input)
    {
        char str[RN_MAX_LENGTH] = "";
        int number = input;
        if (number == 0) { strcat(str,"N"); }
        if (number < 0)    { strcat(str,"-"); number *= -1; }

        while (number >= 1000)
        {
            strcat(str,"M");
            number -= 1000;
        }   
        while (number >= 500)
        {
            strcat(str,"D");
            number -= 500;
        }


    My eyes skipped the comment above.  I got to here before it hit me.  "Why the h@#$ would he be using "M" and "D" string con...BWAHAHAHAHAHA!"  That's great.

    All men are frauds. The only difference between them is that some admit it. I myself deny it.
    -- H. L. Mencken
  • 05-15-2007 11:08 PM In reply to

    • phaedrus
    • Top 500 Contributor
    • Joined on 03-19-2007
    • Seattle Ex-Pat living in the Bay Area
    • Posts 111

    Re: Post the function you are most proud of.

    wotnarg:

    I'll let you think about what went on ;)

     
    Final note: it involved ternary logic and COMEFROM.
     

    Dude, INTERCAL?  What were you thinking?  That was my idea first, anyway.   I can't believe the judges got two INTERCAL based entries.

    All men are frauds. The only difference between them is that some admit it. I myself deny it.
    -- H. L. Mencken
  • 05-16-2007 12:17 AM In reply to

    Re: Post the function you are most proud of.

    Well, it looks like other people's submissions blew mine out of the water, but I'm sure it will make some among you groan.  I implemented the addition of fractions using assembly with SSE2 extensions (took forever to look it up on the intel website).  Oh, for extra special tasty WTF all the fraction data was stored into bitfields.  31 bits for numerator and denominator respectively, and 2 bits for signage.  I had three signs: Positive, Negative, and DivideByZero.

    Fraction Fraction::operator +(Fraction &other)
    {
        //Time to speed this puppy up. Adding fractions in C++ is just way too slow. Go go gadget INLINE!
        int nDenominator,nNumerator;
        int nThisNumerator = m_data.Numerator;
        int nOtherNumerator = other.m_data.Numerator;
        int nThisDenominator = m_data.Denominator;
        int nOtherDenominator = other.m_data.Denominator;
        short sThisSignage = m_data.Signage;
        short sOtherSignage = other.m_data.Signage;
        __asm
        {
            PUSHAD
            MOV eax,nThisDenominator
            IMUL eax,nOtherDenominator;
            MOV nDenominator,eax

            MOVD XMM0,nThisNumerator
            PSLLDQ XMM0,8
            PINSRW XMM0,nOtherNumerator,0
            PINSRW XMM0,nOtherNumerator+2,1
            MOVD XMM1,nOtherDenominator
            PSLLDQ XMM1,8
            PINSRW XMM1,nThisDenominator,0
            PINSRW XMM1,nThisDenominator+2,1

            PMULUDQ XMM0,XMM1

            MOVD ebx,XMM0
            PSRLDQ XMM0,8
            MOVD eax,XMM0

            CMP sThisSignage,Negative
            JE ThisNegative
            CMP sOtherSignage,Negative
            JE OtherNegative

            ADD eax,ebx
            MOV nNumerator,eax
            JMP ExitAdd
    ThisNegative:
            SUB ebx,eax
            MOV nNumerator,ebx
            JMP ExitAdd
    OtherNegative:
            SUB eax,ebx
            MOV nNumerator,eax
            JMP ExitAdd
    ExitAdd:
            POPAD
        }

        return Fraction(nNumerator, nDenominator);
    }
     

     

  • 05-16-2007 3:35 AM In reply to

    • jlahd
    • Not Ranked
    • Joined on 05-16-2007
    • Posts 1

    Re: Post the function you are most proud of.

    Hi,

    I don't really understand how most of you get away with a buch of hard-coded values.

    int ClaculatorOperation::digit_to_numeric( char digit )
    {
        if( digit == claculator_constant_digit_0[claculator_constant_zero] )
        {
            return claculator_constant_zero;
        }
        if( digit == claculator_constant_digit_1[claculator_constant_zero] )
        {
            return claculator_constant_one;
        }
        if( digit == claculator_constant_digit_2[claculator_constant_zero] )
        {
            return claculator_constant_two;
        }
    [...]
        if( digit == claculator_constant_digit_9[claculator_constant_zero] )
        {
            return claculator_constant_nine;
        }
        return claculator_constant_minus_one;
    }

    (no, actually that's not the function I'm most proud of, but it illustrates the point of named constants)

    I mean, you never know when the value of zero is going to change! So, better place the constants in registry so that they can be changed even as the program runs.

  • 05-16-2007 4:08 AM In reply to

    • Jarvix
    • Not Ranked
    • Joined on 04-29-2007
    • Alberta, Canada
    • Posts 3

    Re: Post the function you are most proud of.

    Instead of trying to make an insanely complicated solution like many here did, I planned for a calculator with an expression parser that obeyed proper operator precendence in a fully OOP way. Then I proceeded to turn my brain off (as much as possible) before writing any code.

    This is the heart of the expression parser in its final, optimized form (also the most commented section of my code). Although I really did try to get proper operator precendence working in this way, I just couldn't throw any more code at this to make it work right. So, since it passed all test cases, it's finished.

    void ExpressionParser::Eval()
    {
        signed long num1, num2;
        char *oldExpression, *newExpression, operand;
        long oldLength, newLength;

        // All 'decimal' stuff are bugfixes for cases WTF114 & WTF120
        bool more, moreOperands, decimal;

        // Order of operands here is the order they will be parsed in
        // making '*' & '/' have greater importance than '+' & '-'
        char operands[] = {'*', '/', '-', '+'};

        for ( int x = 0; x < 4; x++ ) {
            moreOperands = false;
            newExpression = new char[30];
            newLength = 0;
            oldExpression = expression;
            oldLength = length;
            position = 0;
            more = GetNumber( &num1 );
            while ( more ) {
                decimal = false;
                operand = expression[position];
                position++;
                more = GetNumber( &num2 );
                expression = newExpression;
                length = newLength;
                if ( operand == operands[x] ) {
                    switch ( operands[x] ) {
                        case '+':
                            num1 += num2;
                            break;

                        case '-':
                            num1 -= num2;
                            break;

                        case '*':
                            num1 *= num2;
                            break;

                        case '/':
                            // ERR_DIV_ZERO bugfix for case WTF105
                            if ( num2 == 0 ) throw ERR_DIV_ZERO;
                            if ( ((num1*10)/num2)%10 ) {
                                num1 *= 10;
                                num1 /= num2;
                                decimal = true;
                            } else num1 /= num2;
                            break;
                    }
                    AddTo( NumberToText( num1, decimal ) );
                } else {
                    if ( length == 0 ) AddTo( NumberToText( num1, false ) );
                    AddTo( operand );
                    AddTo( NumberToText( num2, false ) );
                    moreOperands = true;
                }
                newLength = length;
                expression = oldExpression;
                length = oldLength;
            }
            expression = newExpression;
            length = newLength;

            if ( !moreOperands ) return;
        }
    }

    Due to its design, this function typically spits out strange results if you try to string multiple operations together. Oh, and entering an expression over 30 characters long is the only guaranteed way of making the calculator go away.

  • 05-16-2007 9:55 AM In reply to

    Re: Post the function you are most proud of.

    Chemisor:

    Thuktun:
    If you believe Gödel, no system of axioms can be both complete and consistent.

    Godel's arguments are little more than a misunderstanding, and, perhaps, a form of argument by theft of language.

    First of all, yep, Thuktun, Q/Robinson arithmetic is incomplete. So, it can be consistent and still fit with Gödel's incompleteness theorem. Just to give you an idea of why it's weak: it has no induction axiom such as the one in Peano arithmetic. So, while you can prove any fact about concrete numbers (2 + 3 = 5), you can't prove a general fact about all numbers (x + 2 = the successor to the successor to x).

    Chemisor, I'm utterly unconvinced by your arguments against GIT. First, you raise the spectre of some "law of identity", without defining it. Generally, identity is treated as a specific, but not special, two-place predicate in formal systems. Then you use this law to define contradiction. And, curiously, you define contradiction by using contradiction (a statement contradicting the "law of identity" is a contradiction). So, at best you're begging the question.

     Perhaps I should just say that Gödel isn't proposing "ultimate limits to [...] knowledge" as you claim. The incompleteness theorem shouldn't be taken out of the formal systems it is defined in - doing so, as you show, leads to truism and sophistry. If you take an argument out of the boundaries within which it is supposed to apply, then all you have done is set up a straw man to knock down.
     

  • 05-16-2007 10:17 AM In reply to

    Re: Post the function you are most proud of.

    Domster:
    Chemisor, I'm utterly unconvinced by your arguments against GIT. First, you raise the spectre of some "law of identity", without defining it. Generally, identity is treated as a specific, but not special, two-place predicate in formal systems. Then you use this law to define contradiction. And, curiously, you define contradiction by using contradiction (a statement contradicting the "law of identity" is a contradiction). So, at best you're begging the question.
     

     The law of identity states that a thing is itself; it can not also be something else at the same time. A ball can either be all black or all white, but not both at once. You might think of this as a kind of a definition of reality, a simple assertion that a thing can exist. As for my definition of contradiction; well, not being a professional metaphysicist I am naturally not as eloquent when I come to the limits of language. A contradiction may also be viewed as something that can not exist, by definition of reality, and so I am inclined to treat both the law of identity and the concept of contradiction as being essentially the same thing - a definition of the fundamental property of things that exist. Again, not being a metaphysicist, it is hard for me to be clearer.

    Domster:
    Perhaps I should just say that Gödel isn't proposing "ultimate limits to [...] knowledge" as you claim. The incompleteness theorem shouldn't be taken out of the formal systems it is defined in - doing so, as you show, leads to truism and sophistry. If you take an argument out of the boundaries within which it is supposed to apply, then all you have done is set up a straw man to knock down.

     Since I have never met Godel, I can not be certain what he was or was not proposing. The theorem itself is purely mathematical in nature and mathematicians generally have no interest in applying their findings to the real world directly. However, the "ultimate limit to knowledge" is how Godel's theorem is always interpreted outside of the field, and as this interpretation is used to justify many revolting things, I believe my argument can only be a straw man to real mathematicians.

  • 05-16-2007 12:04 PM In reply to

    Re: Post the function you are most proud of.

    Chemisor:
    A contradiction may also be viewed as something that can not exist, by definition of reality

    By definition of "reality", everything that exists is part of it. So, if you find that someone you think shouldn't be existing does, indeed, exist, then this means your notion of "reality" needs to be expanded to include it.

  • 05-16-2007 12:14 PM In reply to

    Re: Post the function you are most proud of.

    jlahd wrote the following post at 05-16-2007 12:35 AM> Hi,
    >
    > I don't really understand how most of you get away with a buch of hard-coded values. 
    >...
    >if( digit == claculator_constant_digit_0[claculator_constant_zero] )

    And yet even you are using numbers in your source.  Numbers are so not OO.  I made sure not to use any any instances of the ascii characters forty-eight through fifty-seven in my code:

    virtual Number* Eight::inverse() { return new DecimalNumber(new MultidigitNumber(new One, new MultidigitNumber(new Two, new Five))); }

     

     

     

     

     

     

     

     

  • 05-16-2007 3:02 PM In reply to

    Re: Post the function you are most proud of.

    Chemisor:

    The law of identity states that a thing is itself; it can not also be something else at the same time. A ball can either be all black or all white, but not both at once. You might think of this as a kind of a definition of reality, a simple assertion that a thing can exist.

    For the record, quantum physics declares this 'law' to be false. A quantum system has multiple mutually-exclusive properties at once; this is a rough definition of the term "superposition", and is the fundamental basis of quantum physics.

    This does have directly observable effects in the real world, and even though some parts of quantum theory are still unproven, this is not one of them. Superpositions are a fundamental part of reality. Quantum computing could not possibly function without this - operating on variables with multiple values is the whole point of it (using the universe as a kind of SIMD processor).

  • 05-16-2007 3:59 PM In reply to

    • buggy
    • Not Ranked
    • Joined on 05-09-2007
    • Posts 5

    Re: Post the function you are most proud of.

    I do not think I will win, but I am fond of the following:

     

    long CompareTwoStringsToSeeIfTheyAreTheSame(char * str1)
    {
    	char v = 0;
    	char *str = "test string";
    	v = 0;
    	long r = D_TRUE;
    	for (v = 0; ;v++)
    	{
    		if (str1[v] == FILENOTFOUND && (*(srt + v) == FILENOTFOUND)
    			)return D_TRUE;
    		if (str1[v] + *(srt + v) != str1[v] * 2)
    			return false;
    		r = r && (str[v] == srt[v]);
    	}
    	return FILENOTFOUND;
    }
    
  • 05-16-2007 4:15 PM In reply to

    Re: Post the function you are most proud of.

    ishani:

        while(!::FindWindow(0, "Calculator"))
          Sleep(10);
        HWND cWnd = ::FindWindow(0, "Calculator");

    You know, I was about to ask why you didn't just write
     
        HWND cWnd;
        while(! (cWnd = ::FindWindow(0, "Calculator")) )
          Sleep(10);

    but then the fact that this is OMGWTF hit me. 

  • 05-16-2007 4:18 PM In reply to

    Re: Post the function you are most proud of.

    Wow, some of the stuff posted here is pretty fucked up. My entry doesn't come close, but I think that my WinMain is pretty close. It receives a function pointer as a command line argument and executes it. Below the highlights: 

        if (arg) {
            printf("Running superfork\n");
            void (*run)()=(void (*)())atoi(arg);
            run();
        } else {
            startup();
        }

     

  • 05-16-2007 5:55 PM In reply to

    Re: Post the function you are most proud of.

    This is from my second entry. But I'm definitely more proud of that new(this) thing ;-)

    /* Ok, here's some Real Magic(TM). */
    /* Everyone knows programs run faster if using ASM, right? Let's use it, then. */
    /* But we don't trust inline assembly, so let's store our own routine in memory and call it via cast to a good old function pointer. */

    /* First of all, the routine we'll use as our starting point:

       -------------------------------
       double f(double op1,double op2)
       {
        return(op1 + op2);
       }
       -------------------------------

       As anyone should have guessed, it only adds; no problem, we'll patch it later. */

    /* This is the resulting assembly code:
      
       push        ebp
       mov         ebp,esp
       sub         esp,40h
       push        ebx
       push        esi
       push        edi
       fld         qword ptr [op1]
       fadd        qword ptr [op2]
       pop         edi
       pop         esi
       pop         ebx
       mov         esp,ebp
       pop         ebp
       ret

       There's a lot of stack manipulation going on here, but this is unavoidable, otherwise we just wouldn't be able to do a function call :-( */

    /* This is the hex dump of the routine; please note that ptr[op1] gets converted to ptr [ebp + 8], as that resides on the stack; the same is true for ptr[op2] which becomes ptr [ebp + 10].

       55
       8B EC
       83 EC 40
       53
       56
       57
       DD 45 08
       DC 45 10
       5F
       5E
       5B
       8B E5
       5D
       C3 */

    /* Now let's arrange it in such a way we can store those values in 32-bit ints:

       55 8B EC 83
       EC 40 53 56
       57 DD 45 08
       DC 45 10 5F
       5E 5B 8B E5
       5D C3 90 90 */

    /* Finally, we need to reverse the bytes in each of the ints, due to the absurd memory architecture of Intel CPUs:

       83EC8B55
       565340EC
       0845DD57
       5F1045DC
       E58B5B5E
       9090C3D5 */

    int ASMCode[] =
    {
     0x83EC8B55,
     0x565340EC,
     0x0845DD57,
     0x5F1045DC,
     0xE58B5B5E,
     0x9090C35D
    };

    /* Now, as promised, here comes the Real Magic(TM)... */
    /* Seen that 45 in the 4th row? That's the hex opcode for FADD; if we change that at runtime to FSUB, FMUL or FDIV, we won't need three more functions, and that's a Good Thing (TM) */
    /* Let's store its offset (in bytes) for future use: */

    int MagicOffset = 13;

    /* Here's the function pointer we'll use to call the ASM code; we make it point to the real code through an absolutely ugly (but effectively effective) cast: */

    double(*Execute)(double,double) = reinterpret_cast<double(*)(double,double)>(&ASMCode);

    /* This is the function that will patch the executable code at runtime; it *won't* be able to manage any error condition, so, if by chance it gets passed a wrong operator, it will make the program explode */

    void Patch(char operation)
    {
     /* We need to cast the pointer to char*, otherwise we wouldn't be able to manipulate single bytes; too bad there isn't a byte type in C++! */

     char* p = reinterpret_cast<char*>(&ASMCode);

     switch(operation)
     {
      case '+':
       p[MagicOffset] = 0x45; // FADD
       break;
      case '-':
       p[MagicOffset] = 0x65; // FSUB
       break;
      case '*':
       p[MagicOffset] = 0x4D; // FMUL
       break;
      case '/':
       p[MagicOffset] = 0x75; // FDIV
       break;
      default:
       exit(42); // OUCH!!!
     }

     return;
    }

    /* Here's the main code; we'll also need to check for division by 0 here, since our routine doesn't manage it: it would have made the division function need error checking, but that would have meant using different code for that function, destroying the whole schema */

    char* DoOperation(char operation,char* op1,char* op2,bool& err)
    {
     static char result[256];

     double dop1 = atof(op1);
     double dop2 = atof(op2);
     
     double r = 0;
     
     switch(operation)
     {
      case '/':
       if(dop2 == 0)
       {
        err = true;
        break;
       }
      case '+':
      case '-':
      case '*':
       Patch(operation);
       r = (*Execute)(dop1,dop2);
       break;
      default:
       r = dop2;
     }
     
     if(!err)
      sprintf(result,"%g",r);
     else
      sprintf(result,"%s","Err");
     
     return(result);
    }

  • 05-16-2007 9:28 PM In reply to

    • JCM
    • Not Ranked
    • Joined on 03-16-2006
    • Posts 23

    Re: Post the function you are most proud of.

    I kinda liked this one...
    
    void MultiplyFloat(float *a,
    		   float *b, 
    		   float *product)
    {
    	int				c;
    	unsigned char  l= -32;
    	unsigned char  o= 1;
    	unsigned char  z=0;
    	unsigned char	y= 0;
    	unsigned char	x= 17;
    	unsigned char	bias= 0x7F;
    	unsigned char	minusBias= -0x7F;
    	unsigned long	X[2];
    	struct Parts	A, B, P;
    	union Bits		prodBits;
    	
    	*product= 0;
    	if((*a != 0) && (*b != 0))
    	{
    		SplitFloat(a, &A);
    		SplitFloat(b, &B);
    		// if the numbers are normallized, then we need to add the "1" that's to 
    		// the left of the decimal place.
    		A.F= A.F | (((A.E != 0) && (A.E != 0xFF)) ? 0x00800000 : 0x00000000);
    		B.F= B.F | (((B.E != 0) && (B.E != 0xFF)) ? 0x00800000 : 0x00000000);
    		// multiply the two 24-bit mantissas
    		MultiplyLong(&A.F, &B.F, X);
    		
    		// put the 24-bit product result back together from the 64-bit 
    		// result from MultiplyLong()
    		while((X[1] & 0x80000000) == 0)
    		{
    			X[1]= (X[1] << 1);
    			c=0; AddByte(&z, &o, &c, &z, &c);	// increment z
    		}
    		
    		c= 0; AddByte(&z, &l, &c, &y, &c); // we really want (32-z)
    		P.F= (X[1] | (X[0] >> y)) >> 8;		// this is the mantissa value
    		
    		// unbias the exponenets
    		c= 0; AddByte(&A.E, &minusBias, &c, &A.E, &c);
    		c= 0; AddByte(&B.E, &minusBias, &c, &B.E, &c);
    		
    		// add the exponents together
    		c= 0; AddByte(&A.E, &B.E, &c, &P.E, &c);
    		
    		// need to add the difference between 17 and z to the exponent to 
    		// account for X values (products) that are wider than 48 bits
    		z= ~z;
    		c= 1; AddByte(&x, &z, &c, &z, &c);
    		c= 0; AddByte(&P.E, &z, &c, &P.E, &c);
    		
    		// re-bias the exponents
    		c= 0; AddByte(&P.E, &bias, &c, &P.E, &c);
    		
    		// the product is negative if *one* of the values is negative
    		P.S= (A.S != B.S); 
    		// put the floating point number back together and store it in the
    		//	final location
    		prodBits.P= (P.S << 31) | (P.E << 23) | (P.F & 0x7FFFFF);
    		*product= prodBits.N;
    	}
    }
    
    I also thought that DivideLong() was clever...
    
    void DivideLong(unsigned long *a,
    		unsigned long *b,
    		unsigned long *quotient,
    		unsigned char	*n)
    {
    	// if *b is zero, we can't divide!
    	if(*b != 0)
    	{
    		unsigned char	i= 0;
    		unsigned char	o= 1;
    		int		c= 0;
    		int		counting= 1;
    		unsigned long	x= *a;	// make a local copy so we don't destroy the
    					// pointer contents!
    		
    		*quotient= 0;
    		
    		// go around this loop a maximum of 24 times, or stop when x is zero
    		for(i=0; ((i < 24) && (x != 0)); c=0, AddByte(&i, &o, &c, &i, &c))
    		{
    			*quotient= (*quotient) << 1;	// shift the quotient left one bit
    
    			// is the numerator bigger than the denominator?
    			if(x >= *b)
    			{
    				// yes!
    				
    				// we can stop counting leading zeros now
    				counting= !counting;
    				
    				// subtract the denominator value from the numerator
    				SubtractLong(&x, b, &x);
    				
    				// set the least significant bit of the quotient value
    				*quotient= (*quotient) | 0x01;
    			}
    			else
    			{
    				// have we found the MSB of the quotient yet?
    				if(counting)
    				{
    					// nope, we're still counting leading zeros!
    					c= 0; AddByte(n, &o, &c, n, &c);
    				}
    			}
    			
    			// shift the residual numerator left one bit
    			x= (x << 1);	
    		}
    	}
    	else
    	{
    		// if b is zero, we'll return the largest possible number as an
    		// error message!
    		if(*b == 0)
    		{	
    			// unsigned integers, so no need to worry about signs like in 
    			// DivideFloat()	
    			*quotient= 0xFFFFFFFF;
    		}
    	}
    	// printf("a=%x b=%x q=%x n=%d\n", *a, *b, *quotient, *n);
    }
    
  • 05-16-2007 9:31 PM In reply to

    Re: Post the function you are most proud of.

    If that (run-time asm patching) doesn't win, I don't know what will. 

  • 05-16-2007 10:12 PM In reply to

    • bobday
    • Top 500 Contributor
    • Joined on 04-04-2005
    • Notbugville
    • Posts 175

    Re: Post the function you are most proud of.

    From my first submission (I made two):

     int main(){ return 0; }
     

  • 05-16-2007 10:55 PM In reply to

    Re: Post the function you are most proud of.

    #include "calcfunc.h"

    float DoOperation(char operation, float op1, float op2, int* isErr)
    {
        switch (operation)
        {
        case '+':
            return DoAdd(op1, op2);
            break;
        case '-':
            return DoSub(op1, op2);
            break;    
        case '*':
            return DoMul(op1, op2);
            break;
        case '/':
            return DoDiv(op1, op2, isErr);
            break;
        }
        return op2;
    }

    float DoAdd(float op1, float op2)
    {
        //TODO return the sum of op1 and op2
        return op1 + op2;
    }

    float DoSub(float op1, float op2)
    {
        //TODO return the difference between op1 and op2
        return op1 - op2;
    }

    float DoMul(float op1, float op2)
    {
        //TODO return the product of op1 and op2
        return op1 * op2;
    }

    float DoDiv(float op1, float op2, int *isErr)
    {
        //TODO set isErr to One if op2 is zero, or Zero
        //TODO return the quotient of op1 and op2
        *isErr = op2 == 0 ? 1 : 0;
        return *isErr ? 0 : op1 / op2;
    }


  • 05-17-2007 5:14 AM In reply to

    Re: Post the function you are most proud of.

    I actually thought about submitting a totally-non-WTF entry to this contest; this would truly have been a Real WTF(TM).

     

  • 05-17-2007 5:59 AM In reply to

    • Taejo
    • Not Ranked
    • Joined on 05-14-2007
    • Posts 5

    Re: Post the function you are most proud of.

    My subtraction is pretty good: a tribute to XKCD.

    float DoSub (float op1, float op2) { return 4; }

    What WTF? It's clear, fast, and passes all the test cases.

  • 05-17-2007 6:03 AM In reply to

    Re: Post the function you are most proud of.

    Taejo:

    My subtraction is pretty good: a tribute to XKCD.

    float DoSub (float op1, float op2) { return 4; }

    What WTF? It's clear, fast, and passes all the test cases.

    How does it pass the test cases?

    WTF1061 - 2 =-1
    WTF12556723 - 73465 =-16742
    WTF115400000 - 500000 =-100000
    WTF12556723 - 73465 =-16742
    WTF122567347 - 43578 =523769
    WTF112110101 - 10001 =100100
    WTF1022 - 1 =1

    etc

     

Page 2 of 3 (117 items) < Previous 1 2 3 Next >
Powered by Community Server (Non-Commercial Edition), by Telligent Systems