Author Topic: Rounding Numbers  (Read 9039 times)

baden0001

  • Community Member
  • Posts: 5
  • Hero Points: 0
Rounding Numbers
« on: August 28, 2009, 02:31:19 PM »
I am new to this forum and have been using Slickedit for reading through and altering Gcode for CNC Mills.  Been doing it for some 3 years and am happy with Slickedit.  Great program. 

But, now I need to add a function that can round a variable to a certain decimal point.  Example of this:

Variable1=1.34543

needs to be rounded to

Variable1=1.35

Is there a way to do this through macros?

Thanks,
Will Baden

Graeme

  • Senior Community Member
  • Posts: 2812
  • Hero Points: 347
Re: Rounding Numbers
« Reply #1 on: August 29, 2009, 03:52:12 AM »
Create a file something.e or something and add the following code.  Use the load module command on the macro menu to load it.  If you call it from the command line or a menu it will display a message on the command line telling you what options you can use.  If you call it from the command line with
gcode_round n
it will prompt you for the number of decimal places.
If you call it with gcode_round x, it will stop prompting you to confirm each change.
If you call it with gcode_round p it will start prompting you again.
If you bind a key to gcode_round, and use that key to execute it, it will use whatever options you last set.

The call to search searches for the first sequence of digits and decimal point on the current line starting at the current cursor position.  In the call to the search function, the 'R' option means use slickedit regular expressions and the '<' means leave the cursor at the start.  The $ means don't search past the end of the line.  You can see slickedit regular expressions in the help in case you need to change the search - e.g. to look for the '=' before the number.

Graeme


Code: [Select]
#include "slick.sh"

#pragma option(strictsemicolons,on)
#pragma option(strict,on)
#pragma option(autodecl,off)
#pragma option(strictparens,on)



static int gcode_round_places = 2;
static boolean gcode_round_prompt = true;

_command void gcode_round(_str options = '')
{
   if ((last_index('','w') && options == '') || pos(options,'h'))
   {
      message('Option n to select dec. places; p to prompt; x to not prompt');
      return;
   }

   if (pos(options,'n')) {
      _str x1 = prompt('','Enter number of places ',gcode_round_places);
      if (isinteger(x1)) {
         gcode_round_places = (int)x1;
      }
   }

   if (pos(options,'p'))
      gcode_round_prompt = true;

   if (pos(options,'x'))
      gcode_round_prompt = false;

   if (search('[0-9\.]#|$','<R?') == 0)
   {
      _str tx = get_match_text();
      if (length(tx) > 1) {
         replace(tx,round(tx,gcode_round_places), gcode_round_prompt?'':'*');
      }
   }
}


baden0001

  • Community Member
  • Posts: 5
  • Hero Points: 0
Re: Rounding Numbers
« Reply #2 on: August 31, 2009, 01:05:14 PM »
Thanks for the response.

I have tried this code but keep getting bad pragma parameters among others.  Which makes me wonder about version number issues.

We have 2.0b version of slickedit.  What version would we need to allow this to work for us or is there a different way for the version we have?

Thanks for the help,
Will

baden0001

  • Community Member
  • Posts: 5
  • Hero Points: 0
Re: Rounding Numbers
« Reply #3 on: August 31, 2009, 01:16:49 PM »
I tried the round procedure by itself but that procedure was not found.  Is it possible to get the code for that procedure?

Thanks,
Will

Graeme

  • Senior Community Member
  • Posts: 2812
  • Hero Points: 347
Re: Rounding Numbers
« Reply #4 on: August 31, 2009, 08:11:36 PM »
Whoa.  Version 2.0B.  ok, I should have asked what version you are using.

To start with, could you try commenting all the #pragma lines like this

// #pragma

Then add this code before the rest

static _str round(_str x, int places)
{
    return x;
}

Then see if the code will compile and run.  It won't do any rounding but just see if it basically works.  You might need to check your help file on regular expressions.  With slickedit reg expr, you can also use :n to match a floating point number.  I don't know what the replace function will do in your version either.  You could check your help file on pos, last_index, get_match_text, search and replace functions.  If the code basically works, we could write our own round function.  I doubt if I could legally or morally distribute the code for the 14.0.2 round function.

Graeme




baden0001

  • Community Member
  • Posts: 5
  • Hero Points: 0
Re: Rounding Numbers
« Reply #5 on: August 31, 2009, 09:32:23 PM »
Thanks again for responding.

I didn't think about the legalities of copying code, my bad.

As for the code you suggested get_match_text is not supported but the others are.  Slickedit liked the code down to get_match_text after a few tweaks here and there in the code. 

As for a rounding function being written would be great.  If there was a way to round a variable that contains a value instead of searching through the gcode would be great too.

I guess I should get into a little more detail about what is wanted.  The feedrate of a tap (inches per revolution) is known. It would be nice to display this in threads per inch, which can be calculated by 1/(inches per revolution) without having a long decimal.   This calculated value is placed into feedrateTPI variable.  This variable is what needs to be rounded to 2 decimal places.

If I am reading the pos() command correctly, it should be able to tell where the decimal is placed within a variable.  Now to find a procedure that can act on the variable. . .

Thanks,
Will

Graeme

  • Senior Community Member
  • Posts: 2812
  • Hero Points: 347
Re: Rounding Numbers
« Reply #6 on: September 01, 2009, 12:11:43 PM »
Hi

I think you're going to have to use the get_text function, since you don't have get_match_text.  See if you have a get_text function.  If so, you can do something like this

<search for start of the number>
then
typeless pos1;
save_pos(pos1);
int col1 = p_col;
<search for the end of the number>
_str the_number = get_text(p_col - col1);
if (!isnumber(the_number))
    return;

Then to round it to 2 decimal places you could try something like  (untested)
double d = (double)the_number;
int v1 = (d * 1000) + 5;
v1 = v1 / 10;  // drop the bottom digit
int v2 = v1 / 100;
_str res = (_str)v2 :+ '.' :+ (_str)(v1 - (v2*100));

then
restore_pos(pos1);
replace(the_number, res, gcode_round_prompt?'':'*');

To search for the end of the number, a possibility is to use the regular expression [~0-9.]  - this assumes your numbers are always well formed.  You can use the say() function to output diagnostic information  - or _message_box or message  - whatever your system has.

Graeme

DaveyC

  • Senior Community Member
  • Posts: 169
  • Hero Points: 9
Re: Rounding Numbers
« Reply #7 on: September 01, 2009, 12:59:03 PM »
Considering that slickc has heritage with REXX I'm surprised there was not a format() function from
the start. 

baden0001

  • Community Member
  • Posts: 5
  • Hero Points: 0
Re: Rounding Numbers
« Reply #8 on: September 01, 2009, 01:39:55 PM »
Graeme, thanks for all the help!  A version of your code was used for the rounding functions.  I feel kinda sheepish not thinking it through on using simple math.  But I am thankful you did!

Here is what the calculation ended up looking like:

Code: [Select]
v1 = (feedrateTPI * 1000) + 5;
v1 = (int)v1/10;        // drop the bottom digit
v2 = v1/100;            // Bring the decimals back

Daveyc, I looked for format but could not find that procedure, unless it would be under another name.  Bummer.

Again, thanks for all the help,
Will
« Last Edit: September 01, 2009, 01:59:10 PM by baden0001 »