Advertisement
ZoriaRPG

ZScript: Fixed Floats Utilities

May 22nd, 2017
193
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.92 KB | None | 0 0
  1. //! These are in std_functions_prototypes.zh for std.zh (ZC 2.5)
  2. //! Utilities for manipulating values in ZCs floating point fixed madness.
  3.  
  4. //Utilities to set bits (flags) using all decimal places.
  5. //These allows using 30 bits.
  6.  
  7.  
  8. //Sets a flag in the decimal portion of a value.
  9. //The maximum is 10011100001111, but the REALISTIC maximum is 1111111111111 (8191).
  10. int SetDecimalFlag(int var, int flag, bool state){
  11.     int v = GetLowFloat(var);
  12.     if ( state ) v |= flag;
  13.     else v &= ~flag;
  14.     return SetLowFloat(var,v);
  15. }
  16.  
  17. //Extracts the binary value of one bit of a decimal portion of a value.
  18. bool GetDecimalFlag(int var, int flag){
  19.     int v = GetLowFloat(var);
  20.     return ( v & flag ) != 0;
  21. }
  22.  
  23. //Sets a flag int he integer portion of a value.
  24. //The maximum is 110100011011011011, but the REALISTIC maximum is 11111111111111111 (131,071).
  25. int SetIntegerFlag(int var, int flag, bool state){
  26.     int v = GetHighFloat(var);
  27.     if ( state ) v |= flag;
  28.     else v &= ~flag;
  29.     return SetHighFloat(var,v);
  30. }
  31.  
  32. //Extracts the binary value of one bit of the integer portion of a value.
  33. bool GetIntegerFlag(int var, int flag){
  34.     int v = GetHighFloat(var);
  35.     return ( v & flag ) != 0;
  36. }
  37.    
  38.  
  39. //! Utilities to set and get base-10 values to the integer, or decimal portions of a value; or a range therein.
  40.  
  41. //Accepts two inputs, and returns a float where the integer portion
  42. //is the first inout, and the decimal portion is the second.
  43. //Inputs will be automatically truncated, and scaled, as needed.
  44. int SetHighLowFloat(int integer_side, int decimal_side){
  45.     if ( decimal_side >= 0 )
  46.         decimal_side = (decimal_side << 0)/10000;
  47.     if ( integer_side < 0 ) integer_side = integer_side*10000;
  48.     else integer_side = integer_side << 0;
  49.     return integer_side+decimal_side;
  50. }
  51.  
  52. //Accepts a variable, and a value as input, and returns the variable
  53. //with the decimal portion replaced with 'value'.
  54. //If value is an integer, it will be divided by 10000.
  55. //If it is a decimal, it will be translated directly.
  56. int SetLowFloat(int variable, int value){
  57.     int n = variable << 0;
  58.     if ( value >= 0 )
  59.         value = (value << 0)/10000;
  60.     return n+value;
  61. }
  62.  
  63. //Accepts a variable and a value and returns the variable with its integer
  64. //portion replaced with 'value'.
  65. //If value is an integer, it will be truncated automatically.
  66. //If 'value' is a decimal, it will be multipied by 10000.
  67. int SetHighFloat(int variable, int value){
  68.     int n = variable - ( variable << 0 );
  69.     if ( value < 0 ) value = value*10000;
  70.     else value = value << 0;
  71.     return n+value;
  72. }
  73.  
  74. //Takes a float as input 'n', and returns the integer portion as int.
  75. int GetHighFloat(int n) {
  76.     return n >> 0;
  77. }
  78.  
  79. //Takes a float as input 'n', and returns the decimal portion as int.
  80. int GetLowFloat(int n) {
  81.     return (n - (n >> 0)) * 10000;
  82. }
  83.  
  84. //Converts floating point value 'v', after the decimal, to an integer.
  85. int DecimalToInt(int v) {
  86.     int r = (v - (v << 0)) * 10000;
  87.     return r;
  88. }
  89.  
  90.  
  91. //Truncates decimal off floating point value 'v'.
  92. int Truncate(int v) {
  93.     return ( v << 0 );
  94. }
  95.  
  96. //Returns the number of valid integer places in a value.
  97. int NumPlacesInt(int var){
  98.     int q; int num; int numzero; int n;
  99.     for ( q = 0; q <= 4; q++ ) {
  100.         n = GetDigit(var, q);
  101.         if ( n == 0 ) numzero++;
  102.         if ( n != 0 ) {
  103.             num++;
  104.             num+=numzero;
  105.             numzero=0;
  106.         }
  107.     }
  108.     return num;
  109. }
  110.  
  111.  
  112. //Returns the number of valid decimal places in a value.
  113. int NumPlacesDec(int var){
  114.     int q; int num; int numzero; int n;
  115.     for ( q = -1; q >= -4; q-- ) {
  116.         n = GetDigit(var, q);
  117.         if ( n == 0 ) numzero++;
  118.         if ( n != 0 ) {
  119.             num++;
  120.             num+=numzero;
  121.             numzero=0;
  122.         }
  123.     }
  124.     return num;
  125. }
  126.  
  127.  
  128. int GetDigit(int n, int place){ return GetDigitValue(n,place);}
  129.  
  130. //Stores a single-sigit value into a specified place in a variable.
  131. //n is the variable input, place is the place, from a range of 4 to -4
  132. //Storing a value that is larger than can fit in the specified number of places will return an error and -1.
  133. int SetDigit(int v, int place, int value){
  134.     int err[]="Error: The value specified to SetDigit() may only be one place wide.";
  135.     value = value>>0;
  136.     if ( NumPlacesInt(value) > 1 ) {
  137.         TraceS(err);
  138.         return -1;
  139.     }
  140.     place = Clamp(place, -4, 4);
  141.     int n; int q;
  142.     for ( q = -4; q <= 4; q++ ) {
  143.         if ( q != place ) {
  144.             n += GetDigit(v, q); //Store the individual values, except what we want to replace.
  145.         }
  146.         if ( q == place ) {
  147.             n += (value * Pow(10,place)); //Store what we want to replace.
  148.         }
  149.     }
  150.     return n;
  151. }
  152.  
  153. int SetDigitValue(int v, int place, int value){ return SetDigit(v, place, value); }
  154.  
  155. //Stores a value into a specified number of places in a variable.
  156. //n is the variable input, place is the initial place, from a range of 4 to -4
  157. //num is the number of places, and 'value' is the value to store in those places.
  158. //The maximum value is 214747' and decimals will be truncated.
  159. //Passing 99999.9999 will be truncated to 99999.
  160. //Storing a value that is larger than can fit in the specified number of places will return an error and -1.
  161. int SetPartialValue(int n, int place, int num, int value){
  162.     place = Clamp(place, -4, 4);
  163.     int r; int r2 = value << 0;
  164.    
  165.     int err[]="Error: The value specified to SetPartialValue() is wider than the specified value of 'num_places'.";
  166.     //int err2[]="Error: The maximum input value for SetPartialValue(n, place,
  167.     if ( NumPlacesInt(r2) > num ) {
  168.         TraceS(err);
  169.         return -1;
  170.     }
  171.    
  172.     int err2[]="Error: The value specified to SetPartialValue() is narrower than the specified value of 'num_places'.";
  173.     //int err2[]="Error: The maximum input value for SetPartialValue(n, place,
  174.     if ( NumPlacesInt(r2) > num ) {
  175.         TraceS(err2);
  176.         num = NumPlacesInt(r2);
  177.     }
  178.    
  179.     int err3[]="Error: You specified a floating point input 'value' to SetPartialValue() that was truncated.";
  180.     if ( NumPlacesDec(value) > 0 ) {
  181.         TraceS(err3);
  182.     }
  183.    
  184.     int p = 0; int q; int minplace = place-num;
  185.     minplace = Clamp(minplace, -4, 4);
  186.     int maxplace; int temp;
  187.    
  188.     //populate r with the values that we want
  189.     for ( q = place; q >= minplace; q-- ) {
  190.         temp = GetDigit(r2, p);
  191.         SetDigit(r, q, temp);
  192.         p++;
  193.     }
  194.     //then setDigit the rest of its places using n
  195.     for ( q = minplace; q >= -4; q++ ) {
  196.         SetDigit(r, q, n);
  197.     }
  198.     for ( q = place+1; q <= 4; q++ ) {
  199.         SetDigit(r, q, n);
  200.     }
  201.     return r;
  202.    
  203.    
  204. }
  205.  
  206. //Extracts a single digit from n at the place specified.
  207. //-4 is the ten-thousandTHs place, 0 is the ones spot, and 4 is the ten-thousanDs spot.
  208. int GetDigitValue(int n, int place){
  209.     place = Clamp(place, -4, 4);
  210.     if( place < 0 ){
  211.         n = DecimalToInt(n);
  212.         place += 4;
  213.     }
  214.  
  215.     int r = ((n / Pow(10, place)) % 10) << 0;
  216.     return r;
  217. }
  218.  
  219. //Extracts an integer using specific places of any value 'n', from position 'place' plus a number of places 'num'.
  220. int GetPartialValue(int n, int place, int num){
  221.     place = Clamp(place, -4, 4);
  222.     int r;
  223.     int adj = 1;
  224.     for(int i = num-1; i > -1; i--){
  225.         if(place - i < -4) continue;
  226.         r += GetDigitValue(n, place - i) * adj;
  227.         adj *= 10;
  228.     }
  229.     return r;
  230. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement