All pastes #628920 Raw Edit

Anonymous

public text v1 · immutable
·published 2007-07-21 19:46 UTC
rendered paste body
// =====================================================================================================================================
// allen_cpu_lib_math.c - Allen version 2.0
// ===================================================================================================================================== 
//
// This file is part of the Allen Library.
// Last modified: Saturday July 14, 2007.
//
// Copyright (c) 2007, Archville, BSD License.
// A copy can be found here: http://www.opensource.org/licenses/bsd-license.php
// Initally based on Salvatore <antirez> Sanfilippo within Picol 0.1.0
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, 
// are permitted provided that the following conditions are met:
//
//  * Redistributions of source code must retain the above copyright notice, 
//    this list of conditions and the following disclaimer.
//  * Redistributions in binary form must reproduce the above copyright notice, 
//    this list of conditions and the following disclaimer in the documentation 
//    and/or other materials provided with the distribution.
//  * Neither the name of the Garabatos de licor nor the names of its contributors may 
//    be used to endorse or promote products derived from this software 
//    without specific prior written permission.
//
// This software is provided by the copyright holders and contributors
// "as is" and any express or implied warranties, including, but not
// limited to, the implied warranties of merchantability and fitness for
// a particular purpose are disclaimed. in no event shall the copyright owner or
// contributors be liable for any direct, indirect, incidental, special,
// exemplary, or consequential damages (including, but not limited to,
// procurement of substitute goods or services; loss of use, data, or
// profits; or business interruption) however caused and on any theory of
// liability, whether in contract, strict liability, or tort (including
// negligence or otherwise) arising in any way out of the use of this
// software, even if advised of the possibility of such damage.

// =====================================================================================================================================
// Include libraries.
// =====================================================================================================================================

#include <stdio.h>                     // Standard input/output.
#include <stdlib.h>                    // Standard C libraries.
#include <string.h>                    // String libraries.
#include <math.h>                      // Math libraries.
#include <ctype.h>                     // Types and conversion libraries.

#include "allen_interpreter.h"         // Main interpreter library.
#include "allen_parser.h"              // Main parser library.

// =====================================================================================================================================
// Parameters.
// =====================================================================================================================================

#define TLIB_MATH_BSIZE  1024          // Buffer size.

// =====================================================================================================================================
// Possible errors.
// =====================================================================================================================================

#define TLIB_MATH_EHLP  "math.?: command not found in library" // Error: Command not found in math library.

// =====================================================================================================================================
// Tokens.
// ====================================================================================================================================

#define TLIB_MATH_ABS    "math.abs"    // Absolute value.
#define TLIB_MATH_ACC    "math.acos"   // Arc cosine.
#define TLIB_MATH_ACS    "math.asin"   // Arc sine.
#define TLIB_MATH_ACT    "math.atan"   // Arc tangent.
#define TLIB_MATH_AHC    "math.acosh"  // Hyperbolic arc cosine.
#define TLIB_MATH_AHS    "math.asinh"  // Hyperbolic arc sine.
#define TLIB_MATH_AHT    "math.atanh"  // Hyperbolic arc tangent.
#define TLIB_MATH_BAS    "math.base"   // Base conversion.
#define TLIB_MATH_CBR    "math.cbrt"   // Cube root.
#define TLIB_MATH_CIL    "math.ceil"   // Round value up.
#define TLIB_MATH_COS    "math.cos"    // Cosine.
#define TLIB_MATH_CSH    "math.cosh"   // Hyperbolic cosine.
#define TLIB_MATH_DEC    "math.dec"    // Decrement value.
#define TLIB_MATH_EXP    "math.exp"    // Exponent.
#define TLIB_MATH_FLR    "math.floor"  // Round value down.
#define TLIB_MATH_INC    "math.inc"    // Increment value.
#define TLIB_MATH_LOG    "math.log"    // Logarithm.
#define TLIB_MATH_RAM    "math.rand"   // Random number.
#define TLIB_MATH_RND    "math.round"  // Round to next integer.
#define TLIB_MATH_SIN    "math.sin"    // Sine.
#define TLIB_MATH_SSH    "math.sinh"   // Hyperbolic sine.
#define TLIB_MATH_SGN    "math.sign"   // Sign change.
#define TLIB_MATH_SQR    "math.sqrt"   // Square root.
#define TLIB_MATH_TAN    "math.tan"    // Tangent. 
#define TLIB_MATH_TSH    "math.tanh"   // Hyperbolic tangent.

// =====================================================================================================================================
// Helper Function.
// =====================================================================================================================================

#define TLIB_MATH_HLP    "math.?"      // Helper function.

// =====================================================================================================================================
// Basic math operators.
// =====================================================================================================================================

// Allows to perform regular mathematic operations on value lists
// and return results based on their expresions.

// Index:                           Example:         Result:
// AllenVM_CPU_LIB_MATH_ABS(); ::  math.abs   -10    10.000000
// AllenVM_CPU_LIB_MATH_ACC(); ::  math.acos   0.2    1.369438
// AllenVM_CPU_LIB_MATH_ACS(); ::  math.asin   0.2    0.201358
// AllenVM_CPU_LIB_MATH_ACT(); ::  math.atan   0.2    0.197396
// AllenVM_CPU_LIB_MATH_AHC(); ::  math.acosh  20     3.688254
// AllenVM_CPU_LIB_MATH_AHS(); ::  math.asinh  20     3.689504
// AllenVM_CPU_LIB_MATH_AHT(); ::  math.atanh  0.9    1.472219
// AllenVM_CPU_LIB_MATH_BAS(); ::  math.base   10 2  1010
// AllenVM_CPU_LIB_MATH_CBR(); ::  math.cbrt   27     3.000000
// AllenVM_CPU_LIB_MATH_CIL(); ::  math.ceil   23.4  24.000000
// AllenVM_CPU_LIB_MATH_COS(); ::  math.cos    0      1.000000
// AllenVM_CPU_LIB_MATH_CSH(); ::  math.cosh   1      1.543081
// AllenVM_CPU_LIB_MATH_DEC(); ::  math.dec    2 3   -1.000000
// AllenVM_CPU_LIB_MATH_EXP(); ::  math.exp    2      7.389056
// AllenVM_CPU_LIB_MATH_FLR(); ::  math.floor  21.9  21.000000
// AllenVM_CPU_LIB_MATH_INC(); ::  math.inc    2.3    5.000000
// AllenVM_CPU_LIB_MATH_LOG(); ::  math.log    10     2.302585
// AllenVM_CPU_LIB_MATH_RAM(); ::  math.rand   100   78.000000
// AllenVM_CPU_LIB_MATH_RND(); ::  math.round  99.2  99.000000
// AllenVM_CPU_LIB_MATH_SIN(); ::  math.sin    -1    -0.841471
// AllenVM_CPU_LIB_MATH_SSH(); ::  math.sinh   -1    -1.175201
// AllenVM_CPU_LIB_MATH_SGN(); ::  math.sign   +2    -2.000000
// AllenVM_CPU_LIB_MATH_SQR(); ::  math.sqrt   16     4.000000
// AllenVM_CPU_LIB_MATH_TAN(); ::  math.tan    5     -3.380515
// AllenVM_CPU_LIB_MATH_TSH(); ::  math.tanh   5      0.999909

// Total: 25.

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_MATH_ABS();
// Purpose:     Absolute value.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_MATH_ABS(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,argv[0]);                                      // Check parameters.
 float c=abs(atof(argv[1]));                                                             // Calculate.

 char buf[TLIB_MATH_BSIZE];                                                              // Create buffer.
 snprintf(buf,TLIB_MATH_BSIZE,"%f",c);                                                   // Copy result to buffer as float.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_MATH_ACC();
// Purpose:     Arc cosine.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_MATH_ACC(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,argv[0]);                                      // Check parameters.
 float c=acos(atof(argv[1]));                                                            // Calculate.

 char buf[TLIB_MATH_BSIZE];                                                              // Create buffer.
 snprintf(buf,TLIB_MATH_BSIZE,"%f",c);                                                   // Copy result to buffer as float.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_MATH_ACS();
// Purpose:     Arc sine.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_MATH_ACS(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,argv[0]);                                      // Check parameters.
 float c=asin(atof(argv[1]));                                                            // Calculate.

 char buf[TLIB_MATH_BSIZE];                                                              // Create buffer.
 snprintf(buf,TLIB_MATH_BSIZE,"%f",c);                                                   // Copy result to buffer as float.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_MATH_ACT();
// Purpose:     Arc tangent.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_MATH_ACT(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,argv[0]);                                      // Check parameters.
 float c=atan(atof(argv[1]));                                                            // Calculate.

 char buf[TLIB_MATH_BSIZE];                                                              // Create buffer.
 snprintf(buf,TLIB_MATH_BSIZE,"%f",c);                                                   // Copy result to buffer as float.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_MATH_AHC();
// Purpose:     Hyperbolic arc cosine.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_MATH_AHC(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,argv[0]);                                      // Check parameters.
 float c=acosh(atof(argv[1]));                                                           // Calculate.

 char buf[TLIB_MATH_BSIZE];                                                              // Create buffer.
 snprintf(buf,TLIB_MATH_BSIZE,"%f",c);                                                   // Copy result to buffer as float.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_MATH_AHS();
// Purpose:     Hyperbolic arc sine.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_MATH_AHS(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,argv[0]);                                      // Check parameters.
 float c=asinh(atof(argv[1]));                                                           // Calculate.

 char buf[TLIB_MATH_BSIZE];                                                              // Create buffer.
 snprintf(buf,TLIB_MATH_BSIZE,"%f",c);                                                   // Copy result to buffer as float.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_MATH_AHT();
// Purpose:     Hyperbolic arc tangent.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_MATH_AHT(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,argv[0]);                                      // Check parameters.
 float c=atanh(atof(argv[1]));                                                           // Calculate.

 char buf[TLIB_MATH_BSIZE];                                                              // Create buffer.
 snprintf(buf,TLIB_MATH_BSIZE,"%f",c);                                                   // Copy result to buffer as float.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_MATH_BAS();
// Purpose:     Base conversion.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_MATH_BAS(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if (argc != 3)             return AllenVM_CPU_Error(i,argv[0]);                         // Check parameters.
 if (abs(atoi(argv[2]))<2)  return AllenVM_CPU_Error(i,argv[0]);                         // Base should be at least two.
 
 char base_digits[16] =  {'0', '1', '2', '3', '4', '5', '6', '7',                        // Possible base values:
                          '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};                       // From 0 to F, has in hex.
                          
 int index = 0, result[TLIB_MATH_BSIZE];                                                 // Index and result.
 int number = abs(atoi(argv[1])), base = abs(atoi(argv[2]));                             // Number and base to convert.

 while(number != 0) {result[index] = number % base; number = number / base; ++index;}    // While not zero: Apply modulus and divide.

 char buf[TLIB_MATH_BSIZE];                                                              // Create buffer.
 buf[index]='\0'; int c = 0;                                                             // Add \0 to the string.
 for(--index; index>=0; index--,c++)                                                     // Through index values:
   buf[c] = base_digits[result[index]];                                                  // Copy current character.

 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_MATH_CBR();
// Purpose:     Cube root.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_MATH_CBR(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,argv[0]);                                      // Check parameters.
 float c=cbrt(atof(argv[1]));                                                            // Calculate.

 char buf[TLIB_MATH_BSIZE];                                                              // Create buffer.
 snprintf(buf,TLIB_MATH_BSIZE,"%f",c);                                                   // Copy result to buffer as float.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_MATH_CIL();
// Purpose:     Round value up.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_MATH_CIL(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,argv[0]);                                      // Check parameters.
 float c=ceil(atof(argv[1]));                                                            // Calculate.

 char buf[TLIB_MATH_BSIZE];                                                              // Create buffer.
 snprintf(buf,TLIB_MATH_BSIZE,"%f",c);                                                   // Copy result to buffer as float.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_MATH_COS();
// Purpose:     Cosine.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_MATH_COS(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,argv[0]);                                      // Check parameters.
 float c=cos(atof(argv[1]));                                                             // Calculate.

 char buf[TLIB_MATH_BSIZE];                                                              // Create buffer.
 snprintf(buf,TLIB_MATH_BSIZE,"%f",c);                                                   // Copy result to buffer as float.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_MATH_CSH();
// Purpose:     Hyperbolic cosine.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_MATH_CSH(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,argv[0]);                                      // Check parameters.
 float c=cosh(atof(argv[1]));                                                            // Calculate.

 char buf[TLIB_MATH_BSIZE];                                                              // Create buffer.
 snprintf(buf,TLIB_MATH_BSIZE,"%f",c);                                                   // Copy result to buffer as float.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_MATH_DEC();
// Purpose:     Decrement value.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_MATH_DEC(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 3) return AllenVM_CPU_Error(i,argv[0]);                                      // Check parameters.
 float c= atof(argv[1]) - atof(argv[2]);                                                 // Calculate.

 char buf[TLIB_MATH_BSIZE];                                                              // Create buffer.
 snprintf(buf,TLIB_MATH_BSIZE,"%f",c);                                                   // Copy result to buffer as float.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_MATH_EXP();
// Purpose:     Exponent.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_MATH_EXP(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,argv[0]);                                      // Check parameters.
 float c=exp(atof(argv[1]));                                                             // Calculate.

 char buf[TLIB_MATH_BSIZE];                                                              // Create buffer.
 snprintf(buf,TLIB_MATH_BSIZE,"%f",c);                                                   // Copy result to buffer as float.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_MATH_FLR();
// Purpose:     Round value down.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_MATH_FLR(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,argv[0]);                                      // Check parameters.
 float c=floor(atof(argv[1]));                                                           // Calculate.

 char buf[TLIB_MATH_BSIZE];                                                              // Create buffer.
 snprintf(buf,TLIB_MATH_BSIZE,"%f",c);                                                   // Copy result to buffer as float.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_MATH_INC();
// Purpose:     Increment.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_MATH_INC(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 3) return AllenVM_CPU_Error(i,argv[0]);                                      // Check parameters.
 float c= atof(argv[1]) + atof(argv[2]);                                                 // Calculate.

 char buf[TLIB_MATH_BSIZE];                                                              // Create buffer.
 snprintf(buf,TLIB_MATH_BSIZE,"%f",c);                                                   // Copy result to buffer as float.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_MATH_LOG();
// Purpose:     Logarithm.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_MATH_LOG(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,argv[0]);                                      // Check parameters.
 float c=log(atof(argv[1]));                                                             // Calculate.

 char buf[TLIB_MATH_BSIZE];                                                              // Create buffer.
 snprintf(buf,TLIB_MATH_BSIZE,"%f",c);                                                   // Copy result to buffer as float.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_MATH_RAM();
// Purpose:     Random number.
// Returns:     Random number up to argument.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_MATH_RAM(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2)          return AllenVM_CPU_Error(i,argv[0]);                             // Check first parameter.
 if(atoi(argv[1]) == 0) return AllenVM_CPU_Error(i,argv[0]);                             // Check zero value.
 float c=rand() % atoi(argv[1]);                                                         // Calculate.

 char buf[TLIB_MATH_BSIZE];                                                              // Create buffer.
 snprintf(buf,TLIB_MATH_BSIZE,"%f",c);                                                   // Copy result to buffer as float.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_MATH_RND();
// Purpose:     Round to next integer.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_MATH_RND(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,argv[0]);                                      // Check parameters.
 float c = atof(argv[1]); float d = c - (int) c;                                         // Calculate.

 char buf[TLIB_MATH_BSIZE];                                                              // Create buffer.
 snprintf(buf,TLIB_MATH_BSIZE,"%f", d < 0.5 ? floor(c) : ceil(c));                       // Copy result to buffer as float.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_MATH_SIG();
// Purpose:     Sign change.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_MATH_SGN(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,argv[0]);                                      // Check parameters.
 float c=atof(argv[1]) * -1;                                                             // Calculate.

 char buf[TLIB_MATH_BSIZE];                                                              // Create buffer.
 snprintf(buf,TLIB_MATH_BSIZE,"%f",c);                                                   // Copy result to buffer as float.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_MATH_SIN();
// Purpose:     Sine.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_MATH_SIN(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,argv[0]);                                      // Check parameters.
 float c=sin(atof(argv[1]));                                                             // Calculate.

 char buf[TLIB_MATH_BSIZE];                                                              // Create buffer.
 snprintf(buf,TLIB_MATH_BSIZE,"%f",c);                                                   // Copy result to buffer as float.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_MATH_SSH();
// Purpose:     Hyperbolic sine.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_MATH_SSH(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,argv[0]);                                      // Check parameters.
 float c=sinh(atof(argv[1]));                                                            // Calculate.

 char buf[TLIB_MATH_BSIZE];                                                              // Create buffer.
 snprintf(buf,TLIB_MATH_BSIZE,"%f",c);                                                   // Copy result to buffer as float.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_MATH_SQR();
// Purpose:     Square root.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_MATH_SQR(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,argv[0]);                                      // Check parameters.
 float c=sqrt(atof(argv[1]));                                                            // Calculate.

 char buf[TLIB_MATH_BSIZE];                                                              // Create buffer.
 snprintf(buf,TLIB_MATH_BSIZE,"%f",c);                                                   // Copy result to buffer as float.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_MATH_TAN();
// Purpose:     Tangent.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_MATH_TAN(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,argv[0]);                                      // Check parameters.
 float c=tan(atof(argv[1]));                                                             // Calculate.

 char buf[TLIB_MATH_BSIZE];                                                              // Create buffer.
 snprintf(buf,TLIB_MATH_BSIZE,"%f",c);                                                   // Copy result to buffer as float.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_MATH_TSH();
// Purpose:     Hyperbolic tangent.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_MATH_TSH(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,argv[0]);                                      // Check parameters.
 float c=tanh(atof(argv[1]));                                                            // Calculate.

 char buf[TLIB_MATH_BSIZE];                                                              // Create buffer.
 snprintf(buf,TLIB_MATH_BSIZE,"%f",c);                                                   // Copy result to buffer as float.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_MATH_HLP();
// Purpose:     Adds help facilities
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_MATH_HLP(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,argv[0]);                                      // Check parameters.
 
 if(!strcmp(TLIB_MATH_ABS,argv[1])) {                                                    // Compare parameters.
  puts("Description: Returns an absolute value.");                                       // Description.
  puts("Returns: Float positive number from expression result.");                        // Returns.
  puts("Sample: math.abs -2 => 2.000000");                                               // Sample function.
  puts("Parameters: min: 1 max: 1");                                                     // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_MATH_ABS);                                              // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_MATH_ACC,argv[1])) {                                                    // Compare parameters.
  puts("Description: Arc cosine.");                                                      // Description.
  puts("Returns: Float number from expression result.");                                 // Returns.
  puts("Sample: math.acos 0.2 => 1.369438");                                             // Sample function.
  puts("Parameters: min: 1 max: 1");                                                     // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_MATH_ACC);                                              // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_MATH_ACS,argv[1])) {                                                    // Compare parameters.
  puts("Description: Arc sine.");                                                        // Description.
  puts("Returns: Float number from expression result.");                                 // Returns.
  puts("Sample: math.asin 0.2  => 0.201358");                                            // Sample function.
  puts("Parameters: min: 1 max: 1");                                                     // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_MATH_ACS);                                              // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_MATH_ACT,argv[1])) {                                                    // Compare parameters.
  puts("Description: Arc tangent.");                                                     // Description.
  puts("Returns: Float number from expression result.");                                 // Returns.
  puts("Sample: math.atan 0.2 => 0.197396");                                             // Sample function.
  puts("Parameters: min: 1 max: 1");                                                     // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_MATH_ACT);                                              // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_MATH_AHC,argv[1])) {                                                    // Compare parameters.
  puts("Description: Hyperbolic arc cosine.");                                           // Description.
  puts("Returns: Float number from expression result.");                                 // Returns.
  puts("Sample: math.acosh 20 => 3.688254");                                             // Sample function.
  puts("Parameters: min: 1 max: 1");                                                     // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_MATH_AHC);                                              // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_MATH_AHS,argv[1])) {                                                    // Compare parameters.
  puts("Description: Hyperbolic arc sine.");                                             // Description.
  puts("Returns: Float number from expression result.");                                 // Returns.
  puts("Sample: math.asinh 20 => 3.689504");                                             // Sample function.
  puts("Parameters: min: 1 max: 1");                                                     // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_MATH_AHS);                                              // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_MATH_AHT,argv[1])) {                                                    // Compare parameters.
  puts("Description: Hyperbolic arc tangent.");                                          // Description.
  puts("Returns: Float number from expression result.");                                 // Returns.
  puts("Sample: math.atanh 0.9 => 1.472219");                                            // Sample function.
  puts("Parameters: min: 1 max: 1");                                                     // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_MATH_AHT);                                              // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_MATH_BAS,argv[1])) {                                                    // Compare parameters.
  puts("Description: Base conversion.");                                                 // Description.
  puts("Returns: Integer number from expression result.");                               // Returns.
  puts("Sample: math.base 10 2 => 1010");                                                // Sample function.
  puts("Parameters: min: 1 max: 1");                                                     // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_MATH_BAS);                                              // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_MATH_CBR,argv[1])) {                                                    // Compare parameters.
  puts("Description: Returns the cube root of it's argument.");                          // Description.
  puts("Returns: Float number from expression result.");                                 // Returns.
  puts("Sample: math.cbrt 27 => 3.000000");                                              // Sample function.
  puts("Parameters: min: 1 max: 1");                                                     // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_MATH_CBR);                                              // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_MATH_CIL,argv[1])) {                                                    // Compare parameters.
  puts("Description: Round a value up to the next integer.");                            // Description.
  puts("Returns: Float number from expression result.");                                 // Returns.
  puts("Sample: math.ceil 2.124 => 3.000000");                                           // Sample function.
  puts("Parameters: min: 1 max: 1");                                                     // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_MATH_CIL);                                              // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_MATH_COS,argv[1])) {                                                    // Compare parameters.
  puts("Description: Returns the cosine of a given angle.");                             // Description.
  puts("Returns: Float number from expression result.");                                 // Returns.
  puts("Sample: math.cos 0 => 1.000000");                                                // Sample function.
  puts("Parameters: min: 1 max: 1");                                                     // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_MATH_COS);                                              // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_MATH_CSH,argv[1])) {                                                    // Compare parameters.
  puts("Description: Returns the hyperbolic cosine of a given angle.");                  // Description.
  puts("Returns: Float number from expression result.");                                 // Returns.
  puts("Sample: math.cosh 1 => 1.543081");                                               // Sample function.
  puts("Parameters: min: 1 max: 1");                                                     // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_MATH_CSH);                                              // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_MATH_DEC,argv[1])) {                                                    // Compare parameters.
  puts("Description: Decrements a value in N units.");                                   // Description.
  puts("Returns: Float number from expression result.");                                 // Returns.
  puts("Sample: math.dec 100 20 => 80.000000");                                          // Sample function.
  puts("Parameters: min: 2 max: 2");                                                     // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_MATH_DEC);                                              // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_MATH_EXP,argv[1])) {                                                    // Compare parameters.
  puts("Description: Returns the exponential function of arg.");                         // Description.
  puts("Returns: Float number from expression result.");                                 // Returns.
  puts("Sample: math.exp 2 => 7.389056");                                                // Sample function.
  puts("Parameters: min: 1 max: 1");                                                     // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_MATH_EXP);                                              // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_MATH_FLR,argv[1])) {                                                    // Compare parameters.
  puts("Description: Round a value down to the next integer.");                          // Description.
  puts("Returns: Float number from expression result.");                                 // Returns.
  puts("Sample: math.floor 4.524 => 4.000000");                                          // Sample function.
  puts("Parameters: min: 1 max: 1");                                                     // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_MATH_FLR);                                              // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_MATH_INC,argv[1])) {                                                    // Compare parameters.
  puts("Description: Increments a value in N units.");                                   // Description.
  puts("Returns: Float number from expression result.");                                 // Returns.
  puts("Sample: math.inc 100 20 => 120.000000");                                         // Sample function.
  puts("Parameters: min: 2 max: 2");                                                     // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_MATH_INC);                                              // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_MATH_LOG,argv[1])) {                                                    // Compare parameters.
  puts("Description: Returns the natural logarithm of arg.");                            // Description.
  puts("Returns: Float number from expression result.");                                 // Returns.
  puts("Sample: math.log 10 => 2.302585");                                               // Sample function.
  puts("Parameters: min: 1 max: 1");                                                     // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_MATH_LOG);                                              // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_MATH_RAM,argv[1])) {                                                    // Compare parameters.
  puts("Description: Returns a random number from 0 to arg.");                           // Description.
  puts("Returns: Float number from expression result.");                                 // Returns.
  puts("Sample: math.rand 100 => 78.000000");                                            // Sample function.
  puts("Parameters: min: 1 max: 1");                                                     // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_MATH_RAM);                                              // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_MATH_RND,argv[1])) {                                                    // Compare parameters.
  puts("Description: Rounds value to the next integer.");                                // Description.
  puts("Returns: Float number from expression result.");                                 // Returns.
  puts("Sample: math.rand 99.21 => 99.000000");                                          // Sample function.
  puts("Parameters: min: 1 max: 1");                                                     // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_MATH_RND);                                              // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_MATH_SIN,argv[1])) {                                                    // Compare parameters.
  puts("Description: Returns the sine of a given angle.");                               // Description.
  puts("Returns: Float number from expression result.");                                 // Returns.
  puts("Sample: math.sin -1 => -0.841471");                                              // Sample function.
  puts("Parameters: min: 1 max: 1");                                                     // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_MATH_SIN);                                              // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_MATH_SSH,argv[1])) {                                                    // Compare parameters.
  puts("Description: Returns the hyperbolic sine of a given angle.");                    // Description.
  puts("Returns: Float number from expression result.");                                 // Returns.
  puts("Sample: math.sinh -1 => -1.175201");                                             // Sample function.
  puts("Parameters: min: 1 max: 1");                                                     // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_MATH_SSH);                                              // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_MATH_SGN,argv[1])) {                                                    // Compare parameters.
  puts("Description: Changes sign on it's argument.");                                   // Description.
  puts("Returns: Float number from expression result.");                                 // Returns.
  puts("Sample: math.sign +2 => -2.000000");                                             // Sample function.
  puts("Parameters: min: 1 max: 1");                                                     // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_MATH_SGN);                                              // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_MATH_SQR,argv[1])) {                                                    // Compare parameters.
  puts("Description: Returns the square root of arg.");                                  // Description.
  puts("Returns: Float number from expression result.");                                 // Returns.
  puts("Sample: math.sqrt 16 => 4.000000");                                              // Sample function.
  puts("Parameters: min: 1 max: 1");                                                     // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_MATH_SQR);                                              // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_MATH_TAN,argv[1])) {                                                    // Compare parameters.
  puts("Description: Returns the tangent of a given angle.");                            // Description.
  puts("Returns: Float number from expression result.");                                 // Returns.
  puts("Sample: math.tan 5 => -3.380515");                                               // Sample function.
  puts("Parameters: min: 1 max: 1");                                                     // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_MATH_TAN);                                              // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_MATH_TSH,argv[1])) {                                                    // Compare parameters.
  puts("Description: Returns the hyperbolic tangent of a given angle.");                 // Description.
  puts("Returns: Float number from expression result.");                                 // Returns.
  puts("Sample: math.tanh 5 => 0.999909");                                               // Sample function.
  puts("Parameters: min: 1 max: 1");                                                     // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_MATH_TSH);                                              // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 AllenVM_InterpSetResult(i,"");                                                          // Set interpreter result. 
 return AllenVM_CPU_Error(i,TLIB_MATH_EHLP);                                             // Command not found.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_MATH_ADD();
// Purpose:     Add instructions to the CPU.
// Returns:     Void (nothing).
// -------------------------------------------------------------------------------------------------------------------------------------

void AllenVM_CPU_LIB_MATH_ADD(struct AllenInterp *i) {
 AllenVM_InterpSetCommand(i,TLIB_MATH_ABS,   AllenVM_CPU_LIB_MATH_ABS,   NULL);          // Absolute value.
 AllenVM_InterpSetCommand(i,TLIB_MATH_ACC,   AllenVM_CPU_LIB_MATH_ACC,   NULL);          // Arc cosine.
 AllenVM_InterpSetCommand(i,TLIB_MATH_ACS,   AllenVM_CPU_LIB_MATH_ACS,   NULL);          // Arc sine.
 AllenVM_InterpSetCommand(i,TLIB_MATH_ACT,   AllenVM_CPU_LIB_MATH_ACT,   NULL);          // Arc tangent.
 AllenVM_InterpSetCommand(i,TLIB_MATH_AHC,   AllenVM_CPU_LIB_MATH_AHC,   NULL);          // Hyperbolic arc cosine.
 AllenVM_InterpSetCommand(i,TLIB_MATH_AHS,   AllenVM_CPU_LIB_MATH_AHS,   NULL);          // Hyperbolic arc sine.
 AllenVM_InterpSetCommand(i,TLIB_MATH_AHT,   AllenVM_CPU_LIB_MATH_AHT,   NULL);          // Hyperbolic arc tangent.
 AllenVM_InterpSetCommand(i,TLIB_MATH_BAS,   AllenVM_CPU_LIB_MATH_BAS,   NULL);          // Base conversion.
 AllenVM_InterpSetCommand(i,TLIB_MATH_CBR,   AllenVM_CPU_LIB_MATH_CBR,   NULL);          // Cube root.
 AllenVM_InterpSetCommand(i,TLIB_MATH_CIL,   AllenVM_CPU_LIB_MATH_CIL,   NULL);          // Round value up.
 AllenVM_InterpSetCommand(i,TLIB_MATH_COS,   AllenVM_CPU_LIB_MATH_COS,   NULL);          // Cosine.
 AllenVM_InterpSetCommand(i,TLIB_MATH_CSH,   AllenVM_CPU_LIB_MATH_CSH,   NULL);          // Hyperbolic cosine.
 AllenVM_InterpSetCommand(i,TLIB_MATH_DEC,   AllenVM_CPU_LIB_MATH_DEC,   NULL);          // Decrement value.
 AllenVM_InterpSetCommand(i,TLIB_MATH_EXP,   AllenVM_CPU_LIB_MATH_EXP,   NULL);          // Exponent.
 AllenVM_InterpSetCommand(i,TLIB_MATH_FLR,   AllenVM_CPU_LIB_MATH_FLR,   NULL);          // Round value up.
 AllenVM_InterpSetCommand(i,TLIB_MATH_INC,   AllenVM_CPU_LIB_MATH_INC,   NULL);          // Increment value.
 AllenVM_InterpSetCommand(i,TLIB_MATH_LOG,   AllenVM_CPU_LIB_MATH_LOG,   NULL);          // Logarithm.
 AllenVM_InterpSetCommand(i,TLIB_MATH_RAM,   AllenVM_CPU_LIB_MATH_RAM,   NULL);          // Random number. 
 AllenVM_InterpSetCommand(i,TLIB_MATH_RND,   AllenVM_CPU_LIB_MATH_RND,   NULL);          // Round to next integer. 
 AllenVM_InterpSetCommand(i,TLIB_MATH_SGN,   AllenVM_CPU_LIB_MATH_SGN,   NULL);          // Sign change.
 AllenVM_InterpSetCommand(i,TLIB_MATH_SIN,   AllenVM_CPU_LIB_MATH_SIN,   NULL);          // Sine.
 AllenVM_InterpSetCommand(i,TLIB_MATH_SSH,   AllenVM_CPU_LIB_MATH_SSH,   NULL);          // Hyperbolic sine.
 AllenVM_InterpSetCommand(i,TLIB_MATH_SQR,   AllenVM_CPU_LIB_MATH_SQR,   NULL);          // Square root.
 AllenVM_InterpSetCommand(i,TLIB_MATH_TAN,   AllenVM_CPU_LIB_MATH_TAN,   NULL);          // Tangent. 
 AllenVM_InterpSetCommand(i,TLIB_MATH_TSH,   AllenVM_CPU_LIB_MATH_TSH,   NULL);          // Hyperbolic tangent.
 AllenVM_InterpSetCommand(i,TLIB_MATH_HLP,   AllenVM_CPU_LIB_MATH_HLP,   NULL);          // Helper function.  
}

// =====================================================================================================================================
// EOF
// =====================================================================================================================================
// Compiler parameters: Gcc -O2 -lm
// Recommended editor: Scite/Gedit/Vim.