Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Rounding - How do I round to the nearest 20.00? 2

Status
Not open for further replies.

rleiman

Programmer
May 3, 2006
258
US
Hi Everyone,

Can you tell me how to round to the nearest 20.00 or nearest 35.00?

Rounding to the nearest 10.00 or 1.00 is easy because I found a function that does that, but I am not sure if there is something like that to do odd numbers like 20.00

Thanks.
Emad
 
Hi Emad,

This works, even for values like
RoundedVal = RoundToNearest( 42, 2.5 )

Code:
 MAP
   RoundToNearest  (REAL xVal, REAL xRoundTo),REAL
 END

Code:
RoundToNearest  PROCEDURE(REAL xVal, REAL xRoundTo)
 !Assumes that xRoundTo is >= 0
 !When xRoundTo is = 0, then xVal should be returned

_mod    REAL
RetVal  REAL
 CODE
 _mod = xVal % xRoundTo  ! % is the MODULUS operator
 !LRM: (A % B gives the remainder of A divided by B)

 IF _mod >= xRoundTo / 2
    RetVal = xVal + (xRoundTo - _mod)    !Round UP
 ELSE
    RetVal = xVal - _mod                 !Round Down
 END
 
 RETURN Retval

HTH,
Mark Goldberg
 
Hi Mark,

Thanks for the usefull procedure.

This will be my very first stand alone procedure but because of that I don't know how to map it to my app.

Can you tell me the steps needed to map this procedure into my app because I will use that information to create a library of often used procedures, etc.

Is there a special control template I can use to set it up?

Truly.
Emad
 
Hi Emad,

You have a number of choices

a) you can add this procedure to your application just like any other procedure in the APP.
In this case I'd use a SOURCE procedure template
This would be a good excersise to learn how to fill in the template prompts for the parameters and prototypes

b) you can create a new module, which is "external source"
when I do this I typically rename the module from it's default.
you may find it cleanest to provide an include file for the map, this file will be INCLUDE()'d inside of the MODULE statement inside of the map. In other words this file will contain a list of prototypes to be found in the module.

When using this approach, you will want to have sperate modules for any procedures that need to have access to your global scope and other procedures like the RoundToNearest that are completely self contained.

If all of the procedures are completely self contained
then you'll use MEMBER or MEMBER()

If you need to see the scope of myapp.clw then you'll use. MEMBER('myapp.clw')


Code:
  !contents of MyProcs.inc
  RoundToNearest  (REAL xVal, REAL xRoundTo),REAL

Code:
  !contents of MyProcs.clw
  MEMBER
  MAP  
  END
RoundToNearest  PROCEDURE(REAL xVal, REAL xRoundTo) !,REAL
 !Assumes that xRoundTo is >= 0
 !When xRoundTo is = 0, then xVal should be returned

_mod    REAL
RetVal  REAL
 CODE
 _mod = xVal % xRoundTo  ! % is the MODULUS operator
 !LRM: (A % B gives the remainder of A divided by B)

 IF _mod >= xRoundTo / 2
    RetVal = xVal + (xRoundTo - _mod)    !Round UP
 ELSE
    RetVal = xVal - _mod                 !Round Down
 END
 
 RETURN Retval

You might be wondering why I have an empty map
Code:
  MAP
  END
You can think of this as:
Code:
 MAP
   INCLUDE('builtins.clw')
 END
Because that's EXACTLY what the compiler does.
If you were to look at %cwroot%\libsrc\builtins.clw you'd find many of the Runtime Library (RTL) commands. Technically RoundToNearest doesn't need it, but if any procedure in the module uses any of the commands then you will want to have a MAP, even a seemingly empty one.

c) You can create a CLASS
This is how I usually do it, however there are a number of details to explain, so before I embark on that I'd like to know if that's the route you'd like to take.

HTH,
Mark
 
Hi Mark,

Thanks for the reply.

I would like to try out choice "a".

Can you tell me what to put into the prompts of the source procedure template?

Thanks for taking the time to help me.

Truly,
Emad
 
Hi Emad,

I decided to make this as explicit as possible,
so here is what you want to do A-Z

Adding RoundToNearest to an APP as a source procedure:

a) Procedure->New..
b) RoundToNearest
c) Select Procedure Type,
Defaults Tab
Source Procedure
d) Prototype - this goes in the MAP (plus proc name in 'b')
(REAL xVal, REAL xRoundTo),REAL
e) Make sure that Declare Globally is checked
f) Parameters
(REAL xVal, REAL xRoundTo) !,REAL
g) Click on Embeds
ooops bug found in 9053
close out of there
h) Click on OK to save the procedure properties
i) Double click on the procedure
j) Now click on Embeds

k) Double click on "Processed Code" (or highlight it and click INSERT)
l) Select Embed Type:
Highlight Source
Click Select
m) Paste in PART of the code I gave you for the procedure
only that code BELOW the CODE statement
n) click Exit!
o) click Yes (to save)

p) Double click on "Processed Code" (or highlight it and click INSERT)
q) Select Embed Type:
Highlight Source
Click Select
r) Paste in PART of the code I gave you for the procedure
only that code ABOVE the CODE statement
and below the parameters line
s) click Exit!
t) click Yes (to save)

u) click on SOURCE to confirm that your code looks that way you want it to look. Ignore the greyed out lines.
v) exit!
w) close
x) Ok
y) Generate and Compile
z) Sit back and smile

NOTE: when working with multiple SOURCE embed points, I often prefer to work with the EMBEDITOR. OK What's that?

1) On the Application Tree screen of an APP
2) right click on a procedure
3) click on SOURCE
note clicking on module shows you the GENERATED .CLW
any changes made to those are OVERWRITTEN the next time the code is generated.

4) You can enter code into mutiple embeds here, when done click Exit! and Save or throw your changes away.

5) Note you can CONFIGURE
! Start of "___embedName__"
! End of "__embedName__"
! [Priority nnnn]
You can control the text, or even hide them altogether.
see SETUP->Application Options->Embed Editor tab
note you'll have to use the Arrows to see that tab.


HTH,
Mark Goldberg
 
Hi Mark,

W O W !!!!!!!

Thanks for the tutorial.

Your time is very appreciated.

Truly,
Emad
 
Hi Mark,

Thanks to your help I was able to get it to work.

Here is the final code I used.

Thanks again for the time you took.

Truly,
Emad

Code:
RoundToTheNearest    PROCEDURE  (REAL xVal, REAL xRoundTo)  !,REAL ! Declare Procedure
! Start of "Data Section"
! [Priority 4000]
_mod    REAL
RetVal  REAL
! End of "Data Section"
  CODE
! Start of "Add additional DebugHook statements"
! [Priority 5000]

! End of "Add additional DebugHook statements"
! Start of "Processed Code"
! [Priority 4000]
 _mod = xVal % xRoundTo  ! % is the MODULUS operator
 !LRM: (A % B gives the remainder of A divided by B)

 IF _mod >= xRoundTo / 2
    RetVal = xVal + (xRoundTo - _mod)    !Round UP
 ELSE
    RetVal = xVal - _mod                 !Round Down
 END
 
 RETURN Retval
! End of "Processed Code"
! Start of "Procedure Routines"
! [Priority 3500]

! End of "Procedure Routines"
! Start of "Local Procedures"
! [Priority 5000]

! End of "Local Procedures"
 
Hi Emad,

Now do a File --> Selective Export and export only this procedure into a TXA file i.e. RoundingFunc.TXA. So, in your other projects you can just do a File --> Import Text to inport this procedure.

Although you can import from an other application, the TXA approach is safer and portable.

Regards
 
Hi ShankarJ,

Thanks for the info on txa files.

Is it difficult if I want to create a file that holds more than 1 procedure like a library of procedures? If it is not so hard can you tell me how to do it?

Truly,
Emad
 
Hi Emad,

With Selective Export, you can select 1 or many procedures to export. But when you import, you cannot select which procedures to import unless those procedures already exist in the current application and there is a clash which you have to resolve.


I would suggest you put all your procedures/functions into a class i.e. EmadUtil. Create a EmadUtil.inc with the prototypes and definitions of the functions and define the methods in EmadUtil.clw. Check the LIBSRC directory for ideas. This way, all you need to do is add a global include called INCLUDE('EmadUtil.inc') and a global class called

MyUtil CLASS(EmadUtil)
END

With a class you will have the advantage to change/tweak the functionality of the method by overriding the method.

Regards
 
Hi ShankarJ,

Thanks for the information.

It may be a bit confusing until I am more familiar with Clarion.

No, I have not done any templates yet since I am still rather new to Clarion.

I love Clarion. I only wish my employer would have me use Clarion as the front end instead of the buggy Oracle tools such as Oracle Forms and Oracle Reports.

Hopefully, the program I am now developing will get me steady income where I can eventually quit my Oracle Developer job.

Truly,
Emad
 
Emad,

If you wish to share this procedure amongst multiple APPs (and/or PRJs) then go back and read my posting in this thread dated [14 Mar 07 11:06].

Unless you're using the templates to actually generate code, then I would NOT recommend a Selective TXA Export / Import. As this creates a maintenace problem. What happens when you find a bug in one of these procedures? What happens when you add another procedure to the list? Both of those scenarious would require an active and consistent update for each and every APP that is using the code. Whereas the other approaches would accomplish the task with no effort, or thought.

- Mark
 
Hi Mark,

Everything I have done so far is only with the abc templates.

Emad
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top