FGEN Output Decimal Places

dskplc

Member
Join Date
Aug 2013
Location
New Zealand
Posts
119
Hello, I have googled my question without much luck. I am using the FGEN instruction and trying to find out how to control the number of decimal places of the real output. Since one of my outputs was to 7 decimal places a test failed since it wasn't the exact answer to 2 decimal places. I cannot find out in the FGEN instruction how control the number of the decimal places of its output. Has anyone ever encountered this before and have ideas how to correct this? Thanks in advance for help.
 
Comparing REALs with an EQU can easily fail; there are only four values in every [N:N+1) range that can be exactly represented by a float; even fewer when N is around 4 (8?) million and above.

Multiply the FGEN Y and output REAL values by 100, MOVe* the two REALs to be compared to two LINTs, and compare those two LINTs using the EQU.

* you may want to ADD 0.5 before the MOV.
 
Perhaps a bit long winded & there is probably another way but here is some code that effectively strips above two decimal places, you would need to substitute the routines with those in your PLC.

2 decimal places.png
 
@parky's approach is arithmetically the same as mine, but as he notes it is long. This does essentially the same thing; compare the resulting integers using an EQU:

2_decimal_places_drbitboy.png

To do exactly the same thing, arithmetically, as @parky, add a DIV by 100 of the integer outputs of REAL_TO_INT (e.g. Tempint above) and compare the REAL outputs of the DIVs. However, note that if the numbers get too big for INT (327.68), then REAL_TO_DINT would be better, and if numbers get too big for DINT (21,474,836.48), then you are in good company, because you will be up against essentially the same issue that ended the Deep Impact extended mission.

Add 0.5 before the MUL if the instruction that does the conversion from REAL to INT does not do rounding.

An even simpler approach would be to subtract the FGEN output from the target, and if that difference was between -0.005 and +0.005, then the numbers are "equal." N.B. this is not the same as rounding both values to the nearest hundredth, but it is similar.

2_decimal_places_drbitboy_alt.png
 
Last edited:
In Mitsubishi it rounds up if >= 5 or rounds down if < 5 (or what ever decimal place is)
But like most IEEE floats there is a small error in the decimal places on maths functions like 2.0 is actually something like 1.99999998562 (not a real conversion just saying).
I hvae also done it by float to ASCII modify it & convert it back, not tried it recently so not sure if it gives 2 decimal places
 
I have just re-read the OP's question again & a little perplexed, for example the OP said the test failed ?, is this just an exam for example to limit it to 2 decimal places it is usual for example a number of 123.456 rounded to 2 decimal places would be 123.46 as convention usually means if a decimal digit is 5 or above then the previous one should be incremented to one, or if rounded down then it stays at 123.45, if this is a test from a paper then it should state if rounded up or down or it would be unfair to the student. If not stated then both answers would be valid.
Perhaps the OP will enlighten us on it's purpose.
 
As @parky notes, we don't really have enough information from OP about their process and/or what they are trying to do. But that's never stopped us before ;), so here are some random thoughts ...

The basic problem OP has is that they are using an EQUals comparison for binary floating-point values; that is pointless, perhapse even wrong, unless the program either knows the provenance, or takes strict control, of the sub-1.0 fraction of the values being compared, as e.g. @parky's example does in Post #4 of this thread (and as mine does, but in the integer domain). Other than such a special case, EQU should only be used for integers (and strings).

Since OP said they want to do an EQUals comparison to two decimal (base 10) places, it seems reasonable that a deadband of 0.005 is "good enough." So why not use a deadband?

We know one of the values is the output an FGEN instruction.

We do not know the origin of the other value; if it is an HMI with two decimal places, then how would OP know if the HMI rounds in the same manner as the PLC? There are only a small number of cases where it matters (see TL;DR below), but that will make debugging anomalies more difficult.

We do not know the character of the FGEN. Perhaps its input argument is a integer, so there are only so many possible discrete input, and therefore output, values. If so, then maybe it would make more sense to run the other floating-point value backwards through an inverse FGEN, converted that inverted FGEN's output to an integer, and compare that integer with the current integer input to the forward FGEN.

'jes sayin'

TL;DR

In IEEE-754 floating-point representation

  • There can be no more than four fractions in the range [0:1) for which the value is represented exactly with two decimal places: 0.00; 0.25; 0.50; 0.75.
  • There can be no more than four fractions in the range [0:1) for which the third "decimal" place is exactly 5: 0.125; 0.375; 0.625; 0.875.
  • For the other up-to-92 fractions of exactly two decimal places, the rule for rounding from 5 is irrelevant.
 
@DR, The = was what I thought, however, reading his posts it does not mention a check for equals, only the FGEN was at one time 7 DP, no mention of an equals only a test failed what ever that test was. As I said I think we need to know in detail what is trying to be accomplished.
 
@parky: "Since one of my outputs was to 7 decimal places a test failed since it wasn't the exact answer to 2 decimal places" (emphasis mine).

Sounds like an EQU to me, but yeah, mebbe not.

Anyway, we gave them what they asked for; we don't know enough to advocate a better solution until they tell us more. Typical thread.
 
I agree, I also thought at first that it was being used in a EQU, but then again it seems pointless as 99% of the time it would not work, what other calc has 2 decimal places (well they both could even without truncation but this is not likely), it does sound like a test of some sort.
 
What is the range of the device you are running through the FGEN block and how many decimals places do you need to read?
 
Last edited:

Similar Topics

Hi All Can Anyone shed some light on how to use Fgen Function . I have to analyse a pressure and detect a leak. . I want to use a linear graph a...
Replies
1
Views
695
Hey guys, Here at the wastewater treatment plant I'm working on, I have an effluent reservoir that I have a level sensor for, but need to display...
Replies
4
Views
2,035
Does the RX3i have a function generator to linearize a non linear input? Hopefully it supports about 12 break points...
Replies
9
Views
2,739
Since we I've FBD and FGEN block anyone ever use one? My non linear transducer issue is still on the backburner. I've added the block, given it...
Replies
4
Views
4,698
I want to linearize 13 points. The output is to be linearized to a temperature range (0-2400 in 200 degree increments) Where do I enter X and Y...
Replies
4
Views
3,455
Back
Top Bottom