Mitsubishi Truncate Instruction

Try this if you want to find if the number has decimal places that are not 0
So for example if converting the real to integer rounds up or not the result here will be non zero so for example 3.121234 as an integer will be 3
3.146823 will be 4
so by converting the integer back to a float and sub it from the original float will give you a non zero number i.e. either negative or positive so check for non zero therefore you have decimal places

Trunc.png
 
"Is the information provided by drbitboy useful? "

Unfortunately there isnt a TRN instruction, which is the issue




My solution in post #4 did not require the TRN instruction, and it did not use the MOD or MOD_E instruction on a floating-point value.


But since in post #6 you just want to know - True or False - if there is no fractional part to a 32-bit floating point value, something like the following should work (but there are almost certainly better ways to do it):


Assume F32 is the original 32-bit IEEE-754 floating-point value


  • If F32 is 0.0 => return True
  • If -1.0 < F32 AND F32 < 1.0 => return False
  • If F32 > 16,777,215 => return True*
  • if F32 < -16,777,215 => return True*
  • Comment
    • the previous 4 steps would ensure there is no overflow if F32 (Not Equal?) REAL_TO_DINT(DINT_TO_REAL(F32)) was now evaluated
  • Copy F32 bits to 32-bit integer I32
    • Bit-wise AND I32 with 0x7f800000, put result in 32-bit integer EXPONENT
    • Divide EXPONENT by 0x800000, put result back into EXPONENT
    • Subtract EXPONENT from 150**, put result back into EXPONENT
    • MOVe 0 into 32-bit integer MASK
    • OTE MASK/[EXPONENT] (assign 1 to bit [EXPONENT] of MASK)
    • Subtract 1 from MASK, put result back into MASK
    • Bit-wise AND MASK with I32, put result back into I32
    • If I32 > 0 => return False
    • Else => return True




* the comparison constant might be +/-8,388,608 or +/-8,3888,607, instead of 16,777,415
** 150 might be 151 or 149.
 
Last edited:
A simpler approach to describe and code, using two floats and no integers, but with more rungs:

  1. Put absolute value (ABS instruction) of original floating-point value FPV into F32
  2. Assign 8388608.0 into 32-bit floating-point FBIT
  3. Two-steps that will be repeated 24 times total
    1. If F32 is greater than or equal to FBIT then subtract FBIT from F32 and put the result in F32
    2. Divide FBIT by 2.0 and put the result in FBIT
    3. N.B. the rung(s) that does(do) this can be duplicated, and the last DIV op dropped
  4. After 24 executions of step (3) above,
    1. if either
      • FBIT is greater than or equal to 1.0,
      OR
      • FBIT is 0.0,
    2. then the original FPV has no fraction
 
Last edited:
Rather complex that, the one in posts #16/17 is a simple way only 4 instructions
Just convert it to an integer then back to a real compare it with the original if no zero then there are decimal places simple.
 
I did try this, but if the value was 3.0008 for example, I would end up with 3 (Not 3.1), which cause an issue.
Do you need rounding or truncating?

If you need rounding, before doing instructions that Parky wrote add 0.0005 and you will obtain desired result.

For values from 3.0000 to 3.0004 result will be 3.
For values from 3.0005 to 3.0009 result will be 3.1.
 
According to one post from the OP he only wants to know if the float has any decimal places, the above does that if he wants to know what the decimal portion is then this also gives the answer, although due to rounding i.e. 4.593 would round up to 4 so the result would be a negative number but it is not zero
So here is the logic to check for decimal places and extract the decimal places value

Has Decimal places.png
 
Rather complex that, the one in posts #16/17 is a simple way only 4 instructions
Just convert it to an integer then back to a real compare it with the original if no zero then there are decimal places simple.


Yes, and I did say there were better ways (e.g. yours), but I apparently I have too much time on my hands ;).



The only advantage is it will cause no overflows*, but a simple range check**, and using DINTs instead of INTs, added to @parky's code, would accomplish the same.


* Although it does not handle NaNs

* if ABS(FLOAT) is greater than or equal to 2**23 (= 8Mi = 8,388,608), then the the decimal fraction of FLOAT must be zero, assuming FLOAT is single-precision IEEE-754 floating-point.
 
Lol, you & me too, NANs will probably cause a fault as it would happen before during what ever processes the original signal, so there is no real need within this logic, I agree with using double int's just in case the value is outside the integer range but the OP should realise that certainly if I was generating a real number above 32767.0 then I would make them doubles for conversion.
 

Similar Topics

I'm looking to get some spare keys for this PLC. Does anyone know a source or have a part number? My searches are turning up nothing at the moment.
Replies
1
Views
64
I'm struggling to get an FR-E800SCE to work on CC-Link IE TSN. I'm sure the issue is with the drive, when I plug in the network cable I get no...
Replies
1
Views
90
Hi , Where i can find Mitsubishi PLC Card end of line & replacement model details. i am looking for Q02CPU replacement model. Please advice. thanks
Replies
2
Views
126
Hi guys, Im trying to set the real time clock in my Mitsubishi FX1N, but it shows this error ES: 01800001 I have good communication with...
Replies
3
Views
143
Hello there is a way to do the polyfit on 3rd degree on this plc. for imput i have a munimum value of 5 X and 5 Y value for example Measured...
Replies
58
Views
2,583
Back
Top Bottom