How to split a float value to two integer

yojunib

Member
Join Date
Nov 2013
Location
kerala
Posts
25
I need to split a float value eg. XXX.YYY in to two integer contaning values
Int.1 XXX
Int.2 YYY
FLOAT VALUE CAN BE +/-

I have a PLC 5/40 with me...
Can any one help...
 
Use compare instruction to determine +/- then change to a positive value. Do math below. Convert results back (+/-) if that is what you want to do.

(xxx.yyy - .5)=Int.1

(xxx.yyy - Int.1) *1000= Int.2
 
Last edited:
"MOV the Float into Int1 to strip the fraction" but it rounds the number... i don't want any rounding. i want to display a float value in invew for that i need to split the float no into two . one before decimal and one after decimal...
 
MOD the number by 1000, put that result in Int2
MOV the Float into Int1 to strip the fraction. (But I don't recall if it will round the number...)
"MOV the Float into Int1 to strip the fraction" but it rounds the number... i don't want any rounding. i want to display a float value in invew for that i need to split the float no into two . one before decimal and one after decimal...
 
That is crazy! What is inview? If it is a Scada system and cannot display floating point I would be throwing it in the bin!
 
Which PLC/system? Is there instruction list or a like language in use in your system.

Is it possible to use bit level operation to cut and construct the desired values?

PS. I re-read your post PLC5/40 so you have structures text in use? Look how the decimal values are constructed in that PLC in bit level and move the desired bits out of the decimal value, do some math if needed and move the results to the int1&2.
 
Last edited:
"MOV the Float into Int1 to strip the fraction" but it rounds the number... i don't want any rounding. i want to display a float value in invew for that i need to split the float no into two . one before decimal and one after decimal...


Then see my post #3.
 
Just a word of warning for anyone thinking of trying Mickey's method (post #3), on Logix5000 platforms, it won't work as intended, because Logix5000 has adopted the "Round-To-Even" method.

Basically....

Real     Int
0.5 0
1.5 2
2.5 2
3.5 4
4.5 4



So a real odd number like 3.0 will have 0.5 subtracted from it, to become 2.5, then storing that in an INT destination will round it to 2, not 3.

I've witnessed some code conversions from PLC5, SLC, to Logix5000 cause problems because of the different rounding method.
 
If the PLC5/40 has the MOD instruction, then you can...

MOD the floating point number with 1, to reveal only the fractional part, destination a temporary f.p. data-table location.
MUL the fractional part by 10,000, to destination INT2
SUB the fractional part from the original f.p. number, to destination INT1

Note that you will only be able to get max 4 significant digits from either XXX or YYY, because an INT can only hold up to 32,767. That is why I have multiplied the fractional part by 10,000.

example :

Original number = 3.141593 (pi)
MOD 3.141593, 1 = 0.141593
MUL 0.141593, 10000 = 1415.93, but stored into an INT, it will be rounded to 1416
SUB 3.141593, 0.141593 = 3.0, but stored to an INT, rounded to 3

Now that worked OK for pi, and we could have asked for 5 significant digits, but another example proves we can only go to 4....

Original number = 2.718282 (e)
MOD 2.718282, 1 = 0.718282
MUL 0.718282, 10000 = 7182.82, but stored into an INT, it will be rounded to 7183
SUB 2.718282, 0.718282 = 2.0, but stored to an INT, rounded to 2

If we had tried to get 5 sig. digits, the MUL would have resulted in 71828.2, which cant be store in an INT location.

For similar reasons, the highest floating point number we could use this method on would be 32767.xxxx


There is another way, but again it depends if the PLC5/40 has the Truncate (TRN) instruction. This will store in the destination only the whole number part of the f.p. value.

example:

Original number = 3.141593 (pi)
TRN 3.141593 = 3.0, stored to an INT =3
SUB 3.141593, 3 = 0.141593
MUL 0.141593, 10000 = 1415.93, but stored into an INT, it will be rounded to 1416

If neither of those instructions are available, the brute force method is bound to work, but less efficient, and you will need to be careful what floating point number you throw at it (remember it must not be higher than 32767.yyyy) ...

Make the Original number positive (but remember if it was negative).
LES Original, ,0 OTE Neg_flag (a new flag).
ABS Original, Original
or,
XIC Neg_flag : NEG Original
or,
XIC Neg_flag : MUL Original, -1, Original

Copy the new positive original number to a temporary location. I'll call it Temp.
LBL1 : GEQ Temp, 10000 : SUB 10000, Temp : JMP LBL1
LBL2 : GEQ Temp, 1000 : SUB 1000, Temp : JMP LBL2
LBL3 : GEQ Temp, 100 : SUB 100, Temp : JMP LBL3
LBL4 : GEQ Temp, 10 : SUB 10, Temp : JMP LBL4
LBL5 : GEQ Temp, 1 : SUB 1, Temp : JMP LBL5

Temp now holds 0.yyy
Restore the sign of the Original Number
XIC Neg_flag : NEG Original
or,
XIC Neg_flag : MUL Original, -1, Original
INT1 = Original number - Temp
INT2 = Temp * 10000

Lots of ways to do it, at least one of them should work, but remember to LIM the original number because of the INT storage limitations.
 
If the PLC5/40 has the MOD instruction, then you can...

MOD the floating point number with 1, to reveal only the fractional part, destination a temporary f.p. data-table location.
MUL the fractional part by 10,000, to destination INT2
SUB the fractional part from the original f.p. number, to destination INT1

Note that you will only be able to get max 4 significant digits from either XXX or YYY, because an INT can only hold up to 32,767. That is why I have multiplied the fractional part by 10,000.

example :

Original number = 3.141593 (pi)
MOD 3.141593, 1 = 0.141593
MUL 0.141593, 10000 = 1415.93, but stored into an INT, it will be rounded to 1416
SUB 3.141593, 0.141593 = 3.0, but stored to an INT, rounded to 3

Now that worked OK for pi, and we could have asked for 5 significant digits, but another example proves we can only go to 4....

Original number = 2.718282 (e)
MOD 2.718282, 1 = 0.718282
MUL 0.718282, 10000 = 7182.82, but stored into an INT, it will be rounded to 7183
SUB 2.718282, 0.718282 = 2.0, but stored to an INT, rounded to 2

If we had tried to get 5 sig. digits, the MUL would have resulted in 71828.2, which cant be store in an INT location.

For similar reasons, the highest floating point number we could use this method on would be 32767.xxxx


There is another way, but again it depends if the PLC5/40 has the Truncate (TRN) instruction. This will store in the destination only the whole number part of the f.p. value.

example:

Original number = 3.141593 (pi)
TRN 3.141593 = 3.0, stored to an INT =3
SUB 3.141593, 3 = 0.141593
MUL 0.141593, 10000 = 1415.93, but stored into an INT, it will be rounded to 1416

If neither of those instructions are available, the brute force method is bound to work, but less efficient, and you will need to be careful what floating point number you throw at it (remember it must not be higher than 32767.yyyy) ...

Make the Original number positive (but remember if it was negative).
LES Original, ,0 OTE Neg_flag (a new flag).
ABS Original, Original
or,
XIC Neg_flag : NEG Original
or,
XIC Neg_flag : MUL Original, -1, Original

Copy the new positive original number to a temporary location. I'll call it Temp.
LBL1 : GEQ Temp, 10000 : SUB 10000, Temp : JMP LBL1
LBL2 : GEQ Temp, 1000 : SUB 1000, Temp : JMP LBL2
LBL3 : GEQ Temp, 100 : SUB 100, Temp : JMP LBL3
LBL4 : GEQ Temp, 10 : SUB 10, Temp : JMP LBL4
LBL5 : GEQ Temp, 1 : SUB 1, Temp : JMP LBL5

Temp now holds 0.yyy
Restore the sign of the Original Number
XIC Neg_flag : NEG Original
or,
XIC Neg_flag : MUL Original, -1, Original
INT1 = Original number - Temp
INT2 = Temp * 10000

Lots of ways to do it, at least one of them should work, but remember to LIM the original number because of the INT storage limitations.
Thank you it worked...
 

Similar Topics

hey all, I am struggling with a problem here and out of ideas on how else to achieve the desired result. I have a monitor inside a machine with...
Replies
0
Views
121
Hello everyone. I have an PLC L35 (fmw 16) with address 192.168.1.1 and too many connected ethernet devices (3 hmi, a lot of ethernet port, asi...
Replies
11
Views
737
Basic question: I don't understand why Network 4 is split over two lines. I want it to appear like for Network 3, i.e. all on one line. Does...
Replies
1
Views
748
Hello I have a project to record temperature from thermocouple and store it to memory card, the problem is my client didn't provide new...
Replies
11
Views
2,938
Hello, I have following control task. I have to limit a current drawn from a source of power in a grid where I have following power consumptions...
Replies
11
Views
1,966
Back
Top Bottom