H4GA3

      Unfortunately, time can't be turned back.
      In face of new problems that seems unsolvable
      it is useful to see what new tools do we have..

PICO C
======

  https://github.com/zsaleeba/picoc

Installing to Ubuntu-Gnome 17.04 (released 13 April 2017)

  sudo apt-get install libreadline-dev subversion
  git clone https://github.com/zsaleeba/picoc

Remove from makefile '-DVER=\"`svnversion -n`\"'. Hopefully, you used sed to do so:

  cd picoc
  cat Makefile > Makefile.orig
  cat Makefile.orig | sed 's/-DVER=\\\"`svnversion -n`\\\"//' > Makefile
  make
  ./picoc -i
  starting picoc v2.2 beta r
  picoc> int x=5;
  picoc> x=2<<2;
  picoc> printf("%d\n",x);
  8
  picoc> x=2<2;
  picoc> printf("%d\n",x);
  0
  picoc> x=(1>0)?5:4;
  picoc> printf("%d\n",x);
  5

Note: [KeyUp] [KeyDn]   to retrieve commands from history buffer.
      ^d                to exit pico -i

Too primitive? See:

  https://root.cern.ch/
  https://root.cern.ch/cling

C notes
=======

Numbers
-------

  -1.23e-6       float
  123            integer, decimal
  0x12af         integer, hexadecimal

Operations (Subset)
-------------------

  Types:         char int float (unsigned)

  Arithmetics:   +   -   *   /   %
  Logics:        !   &&  ||  ^^
  Bits:          ~   &   |   ^   >>  <<
  Comparison:    <   <=  ==  >=  >   !=
  Ternary:       ?:

  Assignment:    =
  Change order:  ()

  Block:         {}

Function call
-------------

  x = foo( arg, arg..)

ASCII-7
-------

ASCII printable characters

  +----+---------------------------------+
  |    | 0 1 2 3 4 5 6 7 8 9 A B C D E F |
  +----+---------------------------------+
  | 20 |   ! " # $ % & ' ( ) * + , - . / |
  | 30 | 0 1 2 3 4 5 6 7 8 9 : ; < = > ? |
  | 40 | @ A B C D E F G H I J K L M N O |
  | 50 | P Q R S T U V W X Y Z [ \ ] ^ _ |
  | 60 | ` a b c d e f g h i j k l m n o |
  | 70 | p q r s t u v w x y z { | } ~   |
  +----+---------------------------------+

  Example.  41h : A

Quiz test generator
-------------------

quiz-H4.c

  #include <stdio.h>
  #include <stdlib.h>
  #include <time.h>

  enum when { prefix, infix, postfix};
  enum gram { LR, RL, NONE };

  struct operators {
      int   prec;
      char* name;
      int   args;
      enum  when w;
      enum  gram g;
      char* desc;
  };

  struct operators o[] = {
  /*0*/  2, "+" , 1, prefix,  NONE, "unary plus",
  /*1*/  2, "-" , 1, prefix,  NONE, "unary minus",
  /*2*/  2, "!" , 1, prefix,  NONE, "logical NOT",
  /*3*/  2, "~" , 1, prefix,  NONE, "bitwize NOT",
  /*4*/  3, "*" , 2, infix, LR, "multiplication",
  /*5*/  3, "/" , 2, infix, LR, "division",
  /*6*/  3, "%" , 2, infix, LR, "remainder",
  /*7*/  4, "+" , 2, infix, LR, "addition",
  /*8*/  4, "-" , 2, infix, LR, "substraction",
  /*9*/  5, "<<", 2, infix, NONE, "bitwise left shift",
  /*A*/  5, "<<", 2, infix, NONE, "bitwise right shift",
  /*B*/  6, "<" , 2, infix, NONE, "less than",
  /*C*/  6, "<=", 2, infix, NONE, "less or equal",
  /*D*/  6, ">" , 2, infix, NONE, "greater than",
  /*E*/  6, ">=", 2, infix, NONE, "greater or equal",
  /*F*/  7, "==", 2, infix, NONE, "equal",
  /*G*/  7, "!=", 2, infix, NONE, "not equal",
  /*H*/  8, "&" , 2, infix, NONE, "bitwise AND",
  /*I*/  9, "^" , 2, infix, NONE, "bitwise XOR",
  /*J*/ 10, "|" , 2, infix, NONE, "biwise OR",
  /*K*/ 11, "&&", 2, infix, NONE, "logical AND",
  /*L*/ 12, "||", 2, infix, NONE, "logical OR",
  /*M*/ 13, "?:", 3, infix, RL, "ternary conditional"
  };

  int randrange( int afrom, int ato) {
      int rc = afrom +
               (double)(1 + ato - afrom)*((double)rand() / RAND_MAX);
      return rc;
  }

  void quiz(int deep) {
      int r, x;
      r = randrange( 0, 1);
      if (deep == 0) r = 1;
      else if (deep >= 3) r = 0;
      if (r) {
          x = randrange( 0, 22);
          switch( o[x].w) {
              case prefix:
                  printf("(%s", o[x].name);
                  quiz(1+deep);
                  printf(")");
                  break;
              case postfix:
                  printf("(");
                  quiz(1+deep);
                  printf("%s)", o[x].name);
                  break;
              case infix:
                  if (x == 22) {
                      printf("(");
                      quiz(1+deep);
                      printf("?");
                      quiz(1+deep);
                      printf(":");
                      quiz(1+deep);
                      printf(")");
                  }
                  else {
                      printf("(");
                      quiz(1+deep);
                      printf( "%s", o[x].name);
                      quiz(1+deep);
                      printf(")");
                  }
                  break;
           }
      }
      else
          printf("%d", randrange( 0, 100));
  }

  int main() {
      int i;
      srand( time(0));
      for (i=0; i<20; i++) { quiz(0); printf("\n"); }
      return 0;
  }

Annex A. Operations in C (Full list)
------------------------------------

  +----+------------+-----------+-------------------------------------+
  | Nr | Precedence | Operator  | Description, Associativity          |
  +----+------------+-----------+-------------------------------------+
  |  0 | 0          | ()        | Change evaluation order             |
  |  1 | 1          | x++       | Suffix/postfix increment         LR |
  |  2 | 1          | x--       | Suffix/postfix decrement         LR |
  |  3 | 1          | ()        | Function call                       |
  |  4 | 1          | []        | Array subscripting                  |
  |  5 | 1          | .         | Structure and union member access   |
  |  6 | 1          | ->        | member access through pointer*1     |
  |  7 | 1          |(type){lst}| Compound literal(C99)*2             |
  |  8 | 2          | ++        | Prefix increment                 RL |
  |  9 | 2          | --        | Prefix decrement                 RL |
  | 10 | 2          | +         | Unary plus                          |
  | 11 | 2          | -         | Unary minus                         |
  | 12 | 2          | !         | Logical NOT                         |
  | 13 | 2          | ~         | Bitwise NOT                         |
  | 14 | 2          | (type)    | Type cast                           |
  | 15 | 2          | *         | Indirection (dereference)           |
  | 16 | 2          | &         | Address-of                          |
  | 17 | 2          | sizeof    | Size-of                             |
  | 18 | 2          | _Alignof  | Alignment requirement(C11)          |
  | 19 | 3          | *         | multiplication                   LR |
  | 20 | 3          | /         | division                         LR |
  | 21 | 3          | %         | remainder                        LR |
  | 22 | 4          | +         | Addition                            |
  | 23 | 4          | -         | subtraction                         |
  | 24 | 5          | <<        | Bitwise left shift                  |
  | 25 | 5          | >>        | Bitwise right shift                 |
  | 26 | 6          | <         | Less than                           |
  | 27 | 6          | <=        | Less or equal                       |
  | 28 | 6          | >         | Greater than                        |
  | 29 | 6          | >=        | Greater or equal                    |
  | 30 | 7          | ==        | Equal                               |
  | 31 | 7          | !=        | Not Equal                           |
  | 32 | 8          | &         | Bitwise AND                         |
  | 33 | 9          | ^         | Bitwise XOR (exclusive or)          |
  | 34 | 10         | |         | Bitwise OR (inclusive or)           |
  | 35 | 11         | &&        | Logical AND                         |
  | 36 | 12         | ||        | Logical OR                          |
  | 37 | 13         | ?:        | Ternary conditional*3            RL |
  | 38 | 14         | =         | Simple assignment                   |
  | 39 | 14         | +=        | Assignment by sum                   |
  | 40 | 14         | -=        | Assignment by difference            |
  | 41 | 14         | *=        | Assignment by product               |
  | 42 | 14         | /=        | Assignment by quotient              |
  | 43 | 14         | %=        | Assignment by remainder             |
  | 44 | 14         | <<=       | Assignment by bitwise left shift    |
  | 45 | 14         | >>=       | Assignment by bitwise right shift   |
  | 46 | 14         | &=        | Assignment by bitwise AND           |
  | 47 | 14         | ^=        | Assignment by bitwise XOR           |
  | 48 | 14         | |=        | Assignment by bitwise OR            |
  | 49 | 15         | ,         | Comma                            LR |
  +----+------------+-----------+-------------------------------------+

*1) Structure and union
*2) Compound Literals
    https://gcc.gnu.org/onlinedocs/gcc-3.3/gcc/Compound-Literals.html
*3) an assignment-expression is not allowed as the right hand operand of a conditional operator, so e = a < d ? a++ : a = d is an expression that cannot be parsed.

  http://en.cppreference.com/w/c/language
       /operator_precedence#cite_note-1

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Annex B
-------

Some pieces collected from net:

simple String class and test program

  $ g++ StringTest.cpp -o stringtest

String.h

  // Copyright (C) 2009 Ezequiel Gastón Miravalles
  // Cosmetic changes (C) 2017: Kirill Nelus

  #ifndef STRING_H
  #define STRING_H

  #pragma once

  #include <iostream>
  #include <cstring>

  class String
  {
      char *m_pszString;    //Allocated buffer
      int m_nAllocated;    //Allocated length

  public:
      //Construction and destruction
      String();
      ~String();

      //Copy constructors
      String(const char *pszString);
      String(const String& rsString);

      //Operators (assignment)
      String& operator=(const char *pszString);
      String& operator=(const String& rsString);

      //Operators (concatenation)
      String& operator+=(const char *pszString);
      String& operator+=(String& rsString);
      String operator+(String rsString);

      //Operators (comparison)
      bool operator<(String sString);
      bool operator<=(String sString);
      bool operator>(String sString);
      bool operator>=(String sString);
      bool operator==(String sString);
      bool operator!=(String sString);

      //Operations
      void Clear();
      String Lower() { String sTmp = *this; sTmp.MakeLower(); return sTmp; }
      String Upper() { String sTmp = *this; sTmp.MakeUpper(); return sTmp; }

      //Information
      int Length() { return m_pszString?strlen(m_pszString):0; }

      //Cast operators
      operator const char*() { return m_pszString?m_pszString:""; }

  protected:    //Helper functions
      bool Reallocate(int nSize);
      String& MakeLower();
      String& MakeUpper();
  };

  //Output e input
  std::ostream& operator<<(std::ostream& oStream, String& rsString);
  std::istream& operator>>(std::istream& iStream, String& rsString);

  //Consts
  const int cnStringReadBufferSize = 16;
  //------

  String::String() {
      m_pszString = NULL;
      m_nAllocated = 0;
  }

  String::~String() {
      if (m_pszString)
          delete [] m_pszString;
  }

  String::String(const char *pszString) {
      m_pszString = NULL;
      m_nAllocated = 0;
      operator=(pszString);
  }

  String::String(const String& rsString) {
      m_pszString = NULL;
      m_nAllocated = 0;
      operator=(rsString);
  }

  String& String::operator=(const char *pszString)
  {
      if (!pszString)
      {
          Clear();
          return *this;
      }

      int nLen = strlen(pszString);

      if (nLen < m_nAllocated)    //If allocated space is enough
          strcpy(m_pszString, pszString);
      else
      {
          if (m_pszString)
          {
              delete [] m_pszString;
              m_pszString = NULL;
          }

          m_nAllocated = nLen+1;
          m_pszString = new char[m_nAllocated];

          if (!m_pszString)    //Couldn't allocate
              m_nAllocated = 0;
          else
              strcpy(m_pszString, pszString);
      }

      return *this;
  }

  String& String::operator=(const String& rsString) {
      return operator=(rsString.m_pszString);
  }

  void String::Clear()
  {
      if (m_pszString)
          delete [] m_pszString;

      m_pszString = NULL;
      m_nAllocated = 0;
  }

  String& String::operator+=(const char *pszString)
  {
      int nLen = Length() + strlen(pszString);

      if (nLen >= m_nAllocated)    //Reallocation needed
          if (!Reallocate(nLen+1))
              return *this;

      strcat(m_pszString, pszString);

      return *this;
  }

  String& String::operator+=(String& rsString) {
      return operator+=(rsString.m_pszString);
  }

  String String::operator+(String rsString)
  {
      String sString(*this);
      sString += rsString;
      return sString;
  }

  //Operators (comparison)
  bool String::operator<(String sString) {
      return strcmp(operator const char*(), (const char*)sString) < 0;
  }

  bool String::operator<=(String sString) {
      int nCmp = strcmp(operator const char*(), (const char*)sString);
      return nCmp < 0 || nCmp == 0;
  }

  bool String::operator>(String sString) {
      return strcmp(operator const char*(), (const char*)sString) > 0;
  }

  bool String::operator>=(String sString) {
      int nCmp = strcmp(operator const char*(), (const char*)sString);
      return nCmp > 0 || nCmp == 0;
  }

  bool String::operator==(String sString) {
      return strcmp(operator const char*(), (const char*)sString) == 0;
  }

  bool String::operator!=(String sString) {
      return !operator==(sString);
  }

  bool String::Reallocate(int nSize)
  {
      char *pszOldStr = m_pszString;

      m_nAllocated = nSize;
      m_pszString = new char [nSize];

      if (!m_pszString)    //Couldn't allocate
      {
          if (pszOldStr)
              delete [] pszOldStr;
          m_nAllocated = 0;
          return false;
      }

      if (pszOldStr)
      {
          strcpy(m_pszString, pszOldStr);
          delete [] pszOldStr;
      }
      else
          m_pszString[0] = '\0';

      return true;
  }

  String& String::MakeLower()
  {
      if (m_pszString)
          for (int i = 0; m_pszString[i]; i++)
              m_pszString[i] = tolower(m_pszString[i]);

       return *this;
  }

  String& String::MakeUpper()
  {
      if (m_pszString)
          for (int i = 0; m_pszString[i]; i++)
              m_pszString[i] = toupper(m_pszString[i]);

       return *this;
  }

  std::ostream& operator<<(std::ostream& oStream, String& rsString)
  {
      oStream << (const char*)rsString;
      return oStream;
  }

  std::istream& operator>>(std::istream& iStream, String& rsString)
  {
      char pszBuffer[cnStringReadBufferSize];
      pszBuffer[0] = '\0';    //Just in case, we make it a valid string

      rsString.Clear();

      do
      {
          iStream.clear();
          iStream.getline(pszBuffer, cnStringReadBufferSize);
          rsString += pszBuffer;
      } while (iStream.fail() && (!iStream.eof()));

      return iStream;
  }

  #endif // STRING_H

StringTest.cpp

  /*********************************************************************
  Software: Simple String Class Sample Project
  Author: Ezequiel Miravalles
  URL: http://www.neoegm.com/tech/programming/c-cpp/simple-string-class/
  License: GNU GPL v3 (attached, read above)
  Last modification: 08/09/2009
  *********************************************************************/

  #include <iostream>
      using std::cout;
      using std::cin;
      using std::endl;
  #include "String.h"

  using namespace std;

  int main(int argc, char *argv[])
  {
      cout << "String sample project" << endl;
      cout << "---------------------" << endl << endl;

      String a("This"), b("is"), c("a"), d("test");
      String e = a + " " + b + " " + c + " " + d;

      cout << "String parts:" << endl;
      cout << '\t' << a << endl;
      cout << '\t' << b << endl;
      cout << '\t' << c << endl;
      cout << '\t' << d << endl << endl;

      cout << "Concatenated with spaces:" << endl;
      cout << '\t' << e << endl << endl;

      String f, g;

      cout << "Please input a string (hit Enter to break): ";
      cin >> f;
      cout << "Please input other string (hit Enter to break): ";
      cin >> g;

      cout << endl;

      cout << "1st string (" << f << ") is "
           << f.Length() << " chars long." << endl;
      cout << "2nd string (" << g << ") is "
           << g.Length() << " chars long." << endl;

      cout << endl;

      cout << "1st string in lowercase is " << f.Lower() << endl;
      cout << "1st string in uppercase is " << f.Upper() << endl << endl;

      cout << "2nd string in lowercase is " << g.Lower() << endl;
      cout << "2nd string in uppercase is " << g.Upper() << endl << endl;

      cout << "1 < 2\t=> " << (f<g?"true":"false") << endl;
      cout << "1 <= 2\t=> " << (f<=g?"true":"false") << endl;
      cout << "1 > 2\t=> " << (f>g?"true":"false") << endl;
      cout << "1 >= 2\t=> " << (f>=g?"true":"false") << endl;
      cout << "1 == 2\t=> " << (f==g?"true":"false") << endl;
      cout << "1 != 2\t=> " << (f!=g?"true":"false") << endl << endl;

      if (f == g)
          cout << "Strings are equal." << endl;
      else
          cout << "Strings are not equal." << endl;

      cout << endl;

      cout << "1+2\t=> " << f+g << endl;
      cout << "2+1\t=> " << g+f << endl;

      cout << endl;

      return 0;
  }

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Generating random integer values within a range in C
-----------------------------------------------------

  http://stackoverflow.com/questions/15962102
  /generating-random-integer-values-within-a-range-in-c

You should use: M + rand() / (RAND_MAX / (N - M + 1) + 1)

Don't use rand() % N (which tries to return numbers from 0 to N-1) is poor, because the low-order bits of many random number generators are distressingly non-random. (See question 13.18.)

example code (stay calm M>N, everyhing works somehow:):

  #include <stdio.h>      /* printf, scanf, puts, NULL */
  #include <stdlib.h>     /* srand, rand */
  #include <time.h>       /* time */

  int main ()
  {
    int r, i;
    int N = 1,
        M = 12;
    /* initialize random seed: */
    srand (time(NULL));

    /* generate secret number between 1 and 10: */
    for(i=0; i < 10 ; i++){
       r = M + rand() / (RAND_MAX / (N - M + 1) + 1);
       printf("\n%d", r);
    }
    printf("\n") ;
    return EXIT_SUCCESS;
  }

Its working here at codepad

  http://codepad.org/zfAyc24z

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Generate a random double between -1 and 1
-----------------------------------------

  http://stackoverflow.com/questions/33058848
       /generate-a-random-double-between-1-and-1

I think the best way to create a real random double is to use it's structure. Here's an article about how float numbers are stored.

  https://en.wikipedia.org/wiki/IEEE_754-1985

As you see the only limiting condition for float to be between 1 and -1 is that the exponent value doesn't exceed 128.

Ieee754SingleDigits2Double converts string of 0s and 1s to a float variable and return it. I got it from answers to this question.

  #include <stdio.h>
  #include <stdlib.h>
  #include <time.h>

  double Ieee754SingleDigits2Double(const char s[32])
  {
      double f;
      int sign, exp;
      unsigned int mant;
      int i;

      sign = s[0] - '0';

      exp = 0;
      for (i = 1; i <= 8; i++)
          exp = exp * 2 + (s[i] - '0');

      exp -= 127;


      if (exp > -127)
      {

          mant = 1; // The implicit "1."
          exp -= 23;
      }
      else
      {
          mant = 0;
          exp = -126;
          exp -= 23;
      }

      for (i = 9; i <= 31; i++)
          mant = mant * 2 + (s[i] - '0');

      f = mant;

      while (exp > 0)
          f *= 2, exp--;

      while (exp < 0)
          f /= 2, exp++;

      if (sign)
          f = -f;

      return f;
  }

Here's the main function:

  int main(void)
  {
      srand ( time ( NULL));
      int i;
      char s[33];
      for(i = 0; i < 32; i++)
      {
          if(i == 1)
              continue;
          s[i] = rand() % 2 + '0';
      }
      s[1] = '0';
      s[32] = 0;
      printf("%s\n", s);
      printf("%+g\n", Ieee754SingleDigits2Double(s));

      return 0;
  }

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  /*
     A C++ program to implement itoa()
     http://www.geeksforgeeks.org/implement-itoa/
   */

  #include <iostream>
  using namespace std;

  /* A utility function to reverse a string  */
  void reverse(char str[], int length)
  {
      int start = 0;
      int end = length -1;
      while (start < end)
      {
          swap(*(str+start), *(str+end));
          start++;
          end--;
      }
  }

  // Implementation of itoa()

  char* itoa(int num, char* str, int base)
  {
      int i = 0;
      bool isNegative = false;

      /* Handle 0 explicitely, otherwise empty string is printed for 0 */
      if (num == 0)
      {
          str[i++] = '0';
          str[i] = '\0';
          return str;
      }

      // In standard itoa(), negative numbers are handled only with
      // base 10. Otherwise numbers are considered unsigned.
      if (num < 0 && base == 10)
      {
          isNegative = true;
          num = -num;
      }

      // Process individual digits
      while (num != 0)
      {
          int rem = num % base;
          str[i++] = (rem > 9)? (rem-10) + 'a' : rem + '0';
          num = num/base;
      }

      // If number is negative, append '-'
      if (isNegative)
          str[i++] = '-';

      str[i] = '\0'; // Append string terminator

      // Reverse the string
      reverse(str, i);

      return str;
  }

  // Driver program to test implementation of itoa()
  int main()
  {
      char str[100];
      cout << "Base:10 " << itoa(1567, str, 10) << endl;
      cout << "Base:10 " << itoa(-1567, str, 10) << endl;
      cout << "Base:2 " << itoa(1567, str, 2) << endl;
      cout << "Base:8 " << itoa(1567, str, 8) << endl;
      cout << "Base:16 " << itoa(1567, str, 16) << endl;
      return 0;
  }

