LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Integer and fractional part of the number

Hello everybody,
I want to divide the floating point number to 2 integer words, first will receive the interger part of number, and the second will receive the fractional part of the number.
For example: I have number 751.98 in DBL, then I create two integer fields: first has value 751, second has value 98.
I have tried simple conversion from DBL to I16, but it always rounded me to higher interger. I don't want to round it. And I just don't know how to transform the fractional part to integer. Are there any specialized functions for this? Maybe should I use log10 or similar?

TIA,
Jacek.
0 Kudos
Message 1 of 10
(12,441 Views)
Hi,

What if the number is 751.098? The fract part converted to integer would be
98... What if the number is -751.98? Is the fractional part -98 or 98? The
fract part shown is not the real fract part. E.g. 98 will be 9800000001 or
9799999998 (or something like this). So a routine to convert this will
return an integer 9800000001. This might not be what you want.

Best way to work out this kind of problem is using strings. Convert the
number to a string, search for the point. Part before the point will be 751,
the part behind it 098. Convert them back to what you want (or use the
strings for reports).

You can do this using mathimatical functions, but errors are easilly made
(be aware of zero's at begin and and of the real part and fract part, and
negative
numbers, rounding etc.).

Regards,

Wiebe.


"Yazilim" wrote in message
news:5065000000080000008B540000-1027480788000@exchange.ni.com...
> Hello everybody,
> I want to divide the floating point number to 2 integer words, first
> will receive the interger part of number, and the second will receive
> the fractional part of the number.
> For example: I have number 751.98 in DBL, then I create two integer
> fields: first has value 751, second has value 98.
> I have tried simple conversion from DBL to I16, but it always rounded
> me to higher interger. I don't want to round it. And I just don't know
> how to transform the fractional part to integer. Are there any
> specialized functions for this? Maybe should I use log10 or similar?
>
> TIA,
> Jacek.
0 Kudos
Message 2 of 10
(12,441 Views)
Sounds like homework. Will you have repeating decimals? Pi? Root of
2?

Why do you want to do this? There may be better solutions for the
root problem. Unless you really are trying to get us to do your class
work.

There is of course a way to do this.

Mike
0 Kudos
Message 3 of 10
(12,441 Views)
This problem needs some limits. Like: only return the decimal portion
out to 6 places.

First run the number through Remainder and Quotient (divisor of 1).

751.98743674645641000000 gets remainder of

0.98743674645641021900

"floor" is 751

Take the remainder and send through Decimal to Fractional String (this
is where you set your number of decimal places [default is 6]).

returns 0.987437

Then use String Subset and set it to an offset of 2 (cleans off the
leading zero and decimal point) with the "length" input left at the
default of "rest" (of string).

987437 (in string form)

Now use String to Decimal Number

returns 987437 (as a decimal number)
====================================
I think if you don't limit the number of places it is ugly. It is
ugly going from numbers to strings and then back. But all numbers is a
bad thing.

The alogirithm for finding the answer mathematically is nasty.
Especially without a limit on decimal places. You have to figure out
the number of decimal places and multiply by the inverse of the last
decimal place. Sounds easy.
=============================
Try this: New number: 751.98652

Truncate out the remainder (Remainder and Quotient (divisor of 1)):

751.98652 ---> 0.98652

Mult by 10 ----> 9.8652

Take the floor (9) and divide by 10 ----> 0.9

subtract the new number from the old. Is the answer non-zero? Not,
then keep on

0.98652 - 0.9 = .08652 which not equal to 0

If it is zero, the floor is the answer.

Continue - Not:

This time multiply by 100 ----> 98.652

floor is 98, divide by 100 ----> 0.98

Subtract 0.98 from 0.98652 = .00652 still non zero.

Keep on. 1,000, 10,000...When you get to 100,000

0.98652 x 100,000 = 98652.00

Get the floor

divide the floor by 100,000 to get the original number (remainder is
now 0.000), compare to original remainder

0.98652 - 0.98652 = 0. Yay.

Take the 98652 and go with it. The last place was the one hundred
thousandth.

I can't take credit for the last, I had uglier stuff going on. I did
do the string thing.

I swear this is just like some sorry homework problem.

Mike
Message 4 of 10
(12,441 Views)
Jacek,

As indicated above, there needs to be reasonable limits to this conversion. As a double precision number has a range of -Inf to Inf, and a Word has a range of -32687 to 32687, you must sacrifice something.

From your description, I get the sense that you are trying to do this for display purposes only. If that is the case, you have an easy job, as limits do not apply to strings. All you do is use the Match Pattern function and split the string (converted as a fractional string) at the decimal point.

If you are trying to do this as numerics, you have a much tougher assigment. First, you will have to set the range on your control to match the range of your desired result (i.e. 0 to 32687 for Word). Then, you have to 'split' the number.
I would suggest the following to get the first half:

Subtract 0.5
Convert to Integer

This will preclude any rounding up.

To get the second half, just convert a copy of your first half back to DBL, and subtract this value from your original (i.e. 751.98 - 751). This will remove the leading whole number and leave you with your fractional.

Then, multiply by your precision (i.e. 6 decimal places = multiply by 1,000,000 - you did select a preprescribed precision, didn't you) and convert to I16. This will give you your fractional.

I have included code that I wrote to test this method. I set my precision to 3 decimal places. You will have to adjust the constant (1000) if you change the precision. I neglected to set the range on this to match the I16 Limits, so don't forget to do that.
0 Kudos
Message 5 of 10
(12,441 Views)
The place to start with this problem is the IEEE-754 numerical
representations:

32 bit floating point is internally:

highest order bit is the sign bit.

the next 8 bits are the exponent bits

the last 23 bits are the mantissa bits

the mantissas and exponents are binary.

the mantissa value in a 1.22 fixed point binary number, i.e. the most
significant binary bit is equal to 1, the next most is equal to 1/2,
the next most is equal to 1/4, etc., etc.

The exponent part can go between 2^-127 and 2^128

You should be able to cast your 32 bit float to a 32 bit unsigned
integer, separate it into sign, mantissa and exponent parts, use the
exponent to rotate left or right your mantissa decimal point by the
exponent value and then separate the whole part from the fractional
part and then put each into the I16's or U16's as you want.

Douglas De Clue
LabVIEW programmer
ddeclue@bellsouth.net


mross@smpcorp.com (Michael Ross) wrote in message news:...
> This problem needs some limits. Like: only return the decimal portion
> out to 6 places.
>
> First run the number through Remainder and Quotient (divisor of 1).
>
> 751.98743674645641000000 gets remainder of
>
> 0.98743674645641021900
>
> "floor" is 751
>
> Take the remainder and send through Decimal to Fractional String (this
> is where you set your number of decimal places [default is 6]).
>
> returns 0.987437
>
> Then use String Subset and set it to an offset of 2 (cleans off the
> leading zero and decimal point) with the "length" input left at the
> default of "rest" (of string).
>
> 987437 (in string form)
>
> Now use String to Decimal Number
>
> returns 987437 (as a decimal number)
> ====================================
> I think if you don't limit the number of places it is ugly. It is
> ugly going from numbers to strings and then back. But all numbers is a
> bad thing.
>
> The alogirithm for finding the answer mathematically is nasty.
> Especially without a limit on decimal places. You have to figure out
> the number of decimal places and multiply by the inverse of the last
> decimal place. Sounds easy.
> =============================
> Try this: New number: 751.98652
>
> Truncate out the remainder (Remainder and Quotient (divisor of 1)):
>
> 751.98652 ---> 0.98652
>
> Mult by 10 ----> 9.8652
>
> Take the floor (9) and divide by 10 ----> 0.9
>
> subtract the new number from the old. Is the answer non-zero? Not,
> then keep on
>
> 0.98652 - 0.9 = .08652 which not equal to 0
>
> If it is zero, the floor is the answer.
>
> Continue - Not:
>
> This time multiply by 100 ----> 98.652
>
> floor is 98, divide by 100 ----> 0.98
>
> Subtract 0.98 from 0.98652 = .00652 still non zero.
>
> Keep on. 1,000, 10,000...When you get to 100,000
>
> 0.98652 x 100,000 = 98652.00
>
> Get the floor
>
> divide the floor by 100,000 to get the original number (remainder is
> now 0.000), compare to original remainder
>
> 0.98652 - 0.98652 = 0. Yay.
>
> Take the 98652 and go with it. The last place was the one hundred
> thousandth.
>
> I can't take credit for the last, I had uglier stuff going on. I did
> do the string thing.
>
> I swear this is just like some sorry homework problem.
>
> Mike
0 Kudos
Message 6 of 10
(12,441 Views)

I suggest something like this to use with floats different from zero and with 4 decimal digits of precision (x10000):

 

Decimalpart.bmp

0 Kudos
Message 7 of 10
(9,040 Views)

You replied to a 14 year old thread. I am sure you could come up with an even simpler solution Try it! 😄

0 Kudos
Message 8 of 10
(9,028 Views)

Ha, well now it is a 18 year old thread.  But, I needed my code to do the same thing.  This is what I came up with.

Integer_Fraction String Split.png

0 Kudos
Message 9 of 10
(4,397 Views)

Hi martym,

 

and why do you need to convert a number to string, followed by two conversions from string to number?

Btw. your code will not work worldwide…

 

This will basically do the same as yours, but needs to be checked for negative numbers:

Best regards,
GerdW


using LV2016/2019/2021 on Win10/11+cRIO, TestStand2016/2019
0 Kudos
Message 10 of 10
(4,393 Views)