I want to convert a floating point number to a integer number. Basically I have a floating point number between 1 and 0, with three decimal places, and I want to pass it to a integer number as if multiplied by 1000. I suspect there should be a more optimal way to do it than using the arithmetic multiply operation x1000. I'm looking for a piece of code preferably.
-
\$\begingroup\$ Does it really have to be base-10? \$\endgroup\$– drxzclFeb 22, 2011 at 9:04
-
\$\begingroup\$ Is your input stream of FP in IEEE-754 single precision format? In a VHDL program, in a C program? Is your output stream of Int in a signed twos-complement 32 bit format? In a VHDL program, in a C program? Answers to these questions will determine the scope of an answer. Thanks! alan \$\endgroup\$– user3120Feb 22, 2011 at 18:08
-
\$\begingroup\$ I would prefer a solution for base-10 numbers. \$\endgroup\$– PeterstoneFeb 26, 2011 at 9:58
3 Answers
Well, since you don't want to use a power of two for your multiplication, it's going to be a PITA. I'll show you what would be more ideal after answering your question. I'm not going to provide any code - just technique.
The Hard Way (x 1000)
- Multiply the mantissa of your 0-1 number with the mantissa of 1000 (Multiply by a Constant)
- Add the exponent of your 0-1 number with the exponent of 1000 (Add a constant)
- Normalize the mantissa/exponent to the form 1.XXX*2^Y (variable shift, add)
- Adjust the mantissa/exponent so that the exponent is 10 (Can be combined with previous step) (shift, add)
- Take 10 bits of data to the left of the decimal point as your integer
The Easy Way (x 1024)
- Normalize the mantissa for an exponent of 2^10 (variable shift)
- Take the 10 most-significant-bits as your integer value
-
\$\begingroup\$ Rookie question here: what is PITA? \$\endgroup\$ Oct 28, 2014 at 14:14
-
1
If this is not for synthesis, just do it directly:
my_int <= integer(my_real * 1000.0);
If it's for synthesis, then W5VO's "hard way" answer is how you would implement it at the low-level, but I'd instead use David Bishop's synthesizable floating point library fphdl (standardized in VHDL-2008, but useable in any VHDL version) and then just write it similar to the above:
my_sfixed <= to_sfixed(my_float * to_float(1000.0, my_float), my_sfixed);
-
\$\begingroup\$ Link is broken :-(. I can't seem to find an open access equivalent. vhdl.org/downloads/ieee \$\endgroup\$– LeeJul 20, 2016 at 10:56
From a general programming perspective I would use just multiply by 1000 then cast to an integer. I would only look to optimise if if this solution doesn't perform as fast as you want.