You are not registered yet. Please click here to register!


 
 
plc storereviewsdownloads
This board is for PLC Related Q&A ONLY. Please DON'T use it for advertising, etc.
 
Try our online PLC Simulator- FREE.  Click here now to try it.

---------->>>>>Get FREE PLC Programming Tips

New Here? Please read this important info!!!


Go Back   PLCS.net - Interactive Q & A > PLCS.net - Interactive Q & A > LIVE PLC Questions And Answers

PLC training tools sale

Reply
 
Thread Tools Display Modes
Old July 31st, 2009, 03:14 PM   #1
drawson
Member
Canada

drawson is offline
 
Join Date: Aug 2005
Location: Calgary
Posts: 92
RSLogix 5000 - AOI - Rounding

I am trying to create an add-on instruction to round a value.

I have defined the following parameters for the instruction
INPUT: ValueToRound --> REAL
INPUT: Places --> DINT
OUTPUT: RoundedValue --> REAL

I've written the code as follows
IntermediateValue1 = ValueToRound*(10^Places)
DecimalPortion = IntermediateValue1 - TRUNC(IntermediateValue1)
If DecimalPortion >= 0.5 Then
RoundedValue = TRUNC(IntermediateValue1+1)/(10^Places)
Else
RoundedValue = TRUNC(IntermediateValue1)/(10^Places)
End_If

My problem is as follows: If I enter
ValueToRound = 3676.4444
Places = -2

The function calculates the values as 3699.9998 not 3700 as I expected. I assume it has something to do with the floating point math but can't figure out why. Dividing a truncated value by a power of 10 should work.

Any Suggestions?
  Reply With Quote
Old July 31st, 2009, 04:22 PM   #2
TConnolly
Lifetime Supporting Member
United States

TConnolly is offline
 
TConnolly's Avatar
 
Join Date: Apr 2005
Location: Salt Lake City
Posts: 5,709
First off, I have to ask, why are you rounding? Except for display purposes, there is seldom an good reason to round IEEE-754 floats, and the operations to do it are rather complex.

I apologize if this seems a bit pedantic, I'm just trying to explain what the challenges are in what you are trying to do.

There are many numbers that cannot be exactly represented in the IEEE-754 floating point format. 36.764444 happens to be one of those. So right out of the chute, you encounter a problem. This one however doesn't have a say in the outcome, as all you are doing is looking to see is if .764444 is greater than or less than .5.

It is greater than so it seems intuitive that if you add one to 36, giving you 37, you are good do go. But in order to get there, you want to multiply and divide by 10^-2, and here is where you hit a brick wall. 0.01 is another number that cannot be represented in an IEEE float. Instead, .01 becomes .0099999998. Look at the result you actually got and its pretty obvious where this is going. I have even more bad news. Not only is .01 not exactly representable, but .1, .001, .0001, .00001, .... .000000000000000000001, etc are all numbers that cannot be exactly expressed in IEEE-754 float format. And those happen to be the very numbers expressed as 10^-n.

Now modern programs have complex algorithms that round values for display as a string of characters on your computer screen, so you see .01 on your screen, but that is a string, not a number. Inside, in memory it is .0099999998, and when you perform a computation that is what is used.

So, what to do about it?

What is the range of numbers that you will be using? Is the conceivable range of numbers, after shifting the decimal place, within the range of a DINT?
I suspect that they are - besides, long before you exceed the range of a DINT your float will start to suffer from resolution problems that render rounding to two or three decimal places moot, but that is another topic altogether. So if the answer is yes, then I suggest you multiply or divide depending on the sign of n by 10^|n| where 10^|n| is a positive integer, not a float, and make the destination address a DINT. This will automatically round. Then divide or multiply by 10^|n| again depending on the sign of n to an integer destination, then move that to your float.

In your example, start with
CPT XTAG (10**ABS(Places))
XTAG is type DINT
Use XIC Places.31 and XIO Places.32 to see if Places is negative or positive.
because bit Places.31 is set, Places is negative, so divide.
DIV 3676.4444 XTAG DINT_TAG will put 37 in DINT_TAG rounding automatically (well not actually automatically, the processor will jump through all kinds of complex gymnastics to make the conversion, but it will do it for you instead of you coding it.)
Now MUL DINT_TAG XTAG DINT_TAG will put 3700 in DINT_TAG.
Finally, MOV DINT_TAG REAL_TAG

For cases where N is positive, do the opposite, multiply first, then divide.


Over at MRPlc.com in the downloads section http://forums.mrplc.com/index.php?au...s&showfile=761 I have posted a program written for the PLC/5 and SLC500 platforms that does tuncation and rounding by direct manipulation of the IEEE-754 float's mantissa. You can take a look at it and see what's involved behind the scenes, but even it won't work for all possible numbers.


Is places always going to be negative? If so then there are some other easy solutions.

Last of all, I have to ask again, why are you rounding? I'm just asking because we have seen other posts here where someone was attempting to round a number and it really wasn't necessary and boiled down to a misunderstanding of what the number meant and how it was really represented in the processor.
__________________
True craftsmanship is only one more power tool away.

That's the beauty of processors, they don't have emotions they just run code - The PLC Kid.

Last edited by TConnolly; July 31st, 2009 at 05:17 PM.
  Reply With Quote
Old August 5th, 2009, 08:40 AM   #3
drawson
Member
Canada

drawson is offline
 
Join Date: Aug 2005
Location: Calgary
Posts: 92
Alaric thanks for the info.

I am rounding because I am required to do so by specificiation. We produce API well casing and are bound by the specification created by API. They define the hydrostatic test pressure using a calculation based on pipe diameter, wall thickness, and specified minimum yield strength. The result of the calculation is then to be rounded to the nearest 100 psi and used as the test pressure for that particular product.

I decided that while I was creating a rounding routine I had might as well create and AOI that I could reuse rather than just one-time code for this project. I took your advice and used DINT data types instead. Thanks for the help.

I have never fully understood floating point data before. I always thought of it simply as a structure to hold a real number.

Thanks Again.
  Reply With Quote
Old August 5th, 2009, 09:12 AM   #4
TConnolly
Lifetime Supporting Member
United States

TConnolly is offline
 
TConnolly's Avatar
 
Join Date: Apr 2005
Location: Salt Lake City
Posts: 5,709
I'm glad I was able to help.

Here is more info on how floats are stored:http://en.wikipedia.org/wiki/IEEE_754-1985

If you want to see what a particular float looks like in Binary, here is a useful tool:
http://babbage.cs.qc.edu/IEEE-754/Decimal.html


I need to make a correction to my post above. I wrote
Quote:
Use XIC Places.31 and XIO Places.32 to see if Places is negative or positive.
Apparently I fat-fingered the keyboard. It should read:

Use XIC Places.31 and XIO Places.31 to see if Places is negative or positive.

For those who may read this in the future but who don't understand what its doing, bit 31 of any dint is the sign bit. If it is set the number is negative, if it is clear the number is positive.
__________________
True craftsmanship is only one more power tool away.

That's the beauty of processors, they don't have emotions they just run code - The PLC Kid.
  Reply With Quote
Reply
Jump to Live PLC Question and Answer Forum

Bookmarks


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Topics
Thread Thread Starter Forum Replies Last Post
AOI in rslogix 5000 finibx LIVE PLC Questions And Answers 3 July 6th, 2009 01:27 AM
Day of week AOI error in RSLogix 5000 rta53 LIVE PLC Questions And Answers 0 January 9th, 2009 03:17 PM
RSLogix 5000 Add On Instruction (AOI) to HMI NFischer1978 LIVE PLC Questions And Answers 0 September 19th, 2008 06:13 PM
Gray Code and RSLogix 5000 IAA LIVE PLC Questions And Answers 5 September 28th, 2007 09:27 AM
RSLogix 5000 V15 Features Samneggs LIVE PLC Questions And Answers 18 April 20th, 2006 05:45 PM


All times are GMT -5. The time now is 08:15 PM.


.