|
|
View previous topic :: View next topic |
Author |
Message |
kmp84
Joined: 02 Feb 2010 Posts: 345
|
int to float conv. |
Posted: Tue Mar 13, 2018 10:59 am |
|
|
Hello All,
How to convert(faster) long int to float?
Example:
int32 I32 = 123456 -> convert -> 1234.56(Float)?
Thanks!
Last edited by kmp84 on Tue Mar 13, 2018 12:40 pm; edited 1 time in total |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Tue Mar 13, 2018 11:12 am |
|
|
um... 1234.56 is NOT an integer as far as I know... |
|
|
kmp84
Joined: 02 Feb 2010 Posts: 345
|
|
Posted: Wed Mar 14, 2018 5:04 am |
|
|
Any ideas..? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19498
|
|
Posted: Wed Mar 14, 2018 5:07 am |
|
|
Now you have edited it to show what you want.
It is always slightly faster to multiply than divide.
So:
float_val=0.01*I32val;
This will perform a float multiplication (since the 0.01 is automatically a 'float', and put the result into the float val. On a PIC18 for example, the multiplication by 0.01 takes about 1/4 the time needed for /100.
As a separate comment though 'why'?.
Remember that the %w format in printf, can automatically output an integer in a 'float appearance', and that this is performed using integer maths.
So:
printf("%7.2lw", I32);
Will print the integer as 1234.56, without ever involving the time penalty of converting to float. |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Wed Mar 14, 2018 6:07 am |
|
|
I have to agree with the: "Why?" Or more to the point, what, exactly, are you concerned about?
Floating point operations take a lot longer than the equivalent integer versions. That's a fact of computing life. Personally I'm not so averse to floating point as some other people here are. I much prefer to work in scaled integers in engineering units rather than raw ADC/sensor values. that scaling will generally required at least a floating multiplcation and often an addition (for offsetting). I do avoid divisions, organising my scaling factors to make them multiplicative. I cannot, realistically, avoid doing this somewhere in my code. However, I make sure I'm only doing it once, and only after all other processing has been done, such as averaging, filtering and so on: I will do those in integers.
I do not scale each and every ADC reading. I ensure I'm only doing the floating point scaling when I have to, I do not scale each and every ADC reading. Often I will not scale until its required/requested by the outside world.
I long since (as in the mid-seventies when I was in my youth) gave up on the idea that computers were all, and only about absolute speed. Fast enough is fast enough, and while I have done code and hardware optimisation, I only do it where it is absolutely necessary as it takes a lot of time, generally for little meaningful gain. Also that alternative algorithms, i.e. doing the job in a different way, often provides far more, and far more cost-effective speed gains than keyhole optimising. By "keyhole" optimising I mean this sort of "is there a faster way to divide?" locallissed optimisation of code elements rather than lookign at the process as a whole and asking "do I need to divide at all?" I take the view that much of the computing world took decades ago: if you want something to run faster, buy a faster processor.
On a related point I generally run my PICs at their highest clock speed, only slowing them down (e.g. turning off PLLs) where lower power consumption is necessary and where the improvement is significant. As I nearly always have speed sensitive comms link and run my PICs in relatively hot environments, e.g. RF power modules, I almost never use internal clock, preferring external crystals.
So, if you're worried abotu making your code run faster, then the first question is is it already running fast enough? If so why do anything more? |
|
|
kmp84
Joined: 02 Feb 2010 Posts: 345
|
|
Posted: Wed Mar 14, 2018 6:19 am |
|
|
Hello Mr."Ttelmah" and Mr."temtronic"
Sorry for my mistake (1234.56)
This equation will do the job Quote: | float_val=0.01*I32val; |
There is little problem with rounding, from (int32)123456 get (float) 1234.55 but for now it's OK.
Another way as Mr.Ttelmah pointing is : Code: |
#include <stdlib.h>
char string [10];
int32 i32 = 123456;
float x;
sprintf(string, "%7.2lw", i32);
x = atof(string);
|
but this may be much slower than the above?
Thanks. |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Wed Mar 14, 2018 6:41 am |
|
|
kmp84 wrote: |
This equation will do the job Quote: | float_val=0.01*I32val; |
There is little problem with rounding, from (int32)123456 get (float) 1234.55 but for now it's OK.
|
You can never precisely divide or multiply by 0.1, 0.01 etc. using binary floating point, or binary floating point with binary exponent, as IEEE754 does. The reason is that 0.01 (and 0.1 and so on) cannot be precisely represented in binary. When you multiply by 0.01, what you are really doing is mulitplying by something like 0.09999963, which may, or may not be rounded when printed. If you do not take account of this by careful rounding (and watch those negative numbers...) then you are relying on the conversions performed by formatting code, such as printf and so on, which may well not do what you expect. Again, the integer code normally does a better job of such things.
atof() will almost certainly be much slower than a simple divide. |
|
|
kmp84
Joined: 02 Feb 2010 Posts: 345
|
|
Posted: Wed Mar 14, 2018 6:55 am |
|
|
Hello Mr."RF_Developer",
I know how hard and slow are floating point value for microcontrollers, but in my current project I have to communicate with PC Software that accept only float or double IEEE754 value over modbus protocol and have to adapt to it!
In this project I'm using dsPic33EP512MU810 running at 120MHz.
I have another two important question for this dsPic, but will start in another topic.
Thank you my Friends! |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Wed Mar 14, 2018 6:59 am |
|
|
As others have pointed out we need to know HOW you're using the number. Is it for an actual 'calculation' or just to 'display' ?
If for a 'calculation', then yes floating point is a lot slower that integer math. As well FP numbers are not precise! Computers deal in ones and zeros NOT decimal pointed numbers. That is true of ALL computers, not just PICs.
I suspect the FP math in CCS C is fairly 'optimised' for speed, though I've never looked at the code. I do know it's faster than displaying data on an LCD module and a LOT faster than my typing abilities !
Jay |
|
|
kmp84
Joined: 02 Feb 2010 Posts: 345
|
|
Posted: Wed Mar 14, 2018 7:21 am |
|
|
Hi Mr."temtronic",
Quote: | As others have pointed out we need to know HOW you're using the number. Is it for an actual 'calculation' or just to 'display' ? |
Yes it's for display, I get for example integer value 1234 which is 12.34 kg, liters ...etc adding them to int32 totalizer and have to send over modbus protocol as single or double IEEE754 float to PC. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Wed Mar 14, 2018 7:44 am |
|
|
Since you're using Modbus and a PC, I suspect slow 'speed' may be the actual serial communications ( typically 9600 for Modbus ??) and not the FP calcuation. A PIC at 120MHz is mighty fast and should easly do the 'FP math'. Then there's the PC side of the wires. Are you using a real comport or some USB module, which OS, how many applications/progras running, etc.? All this and more will affect overall performance. |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Wed Mar 14, 2018 7:54 am |
|
|
kmp84 wrote: | I know how hard and slow are floating point value for microcontrollers, but in my current project I have to communicate with PC Software that accept only float or double IEEE754 value over modbus protocol and have to adapt to it! |
Fine, but an occasional floating multiply or divide is not going to take all that long, so just do it, esepcially on a dsPIC at 120MHz. I'd be happy to take that relatively small hit on a 18 at 10MHz. Its only going to be significant if your code is tightly looping. On Modbu, you can even do it only when the data is asked for, i.e. occasionally and on demand rather than every sensor reading "Just in case". The overhead is hardly worth worrying about, and the improvement by doing floating multiply rather than divide is the easiest and most effective. |
|
|
kmp84
Joined: 02 Feb 2010 Posts: 345
|
|
Posted: Wed Mar 14, 2018 8:47 am |
|
|
First thank you very much friends!
I'm running dsPic at 120MHz because using TCP/IP Server, two serial port at 9600 (one modbus RTU and one non-standart serial protocols) and some double floats calc. but this may not be necessary (run at 120MHz)?
Best Regards! |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Wed Mar 14, 2018 8:57 am |
|
|
I never have run a TCP/IP server so I can't speak about the speed needed for it but 9600 baud is about 1 character/millsecond, as a reference.
Now, 2 decades ago, I had a PIC16F877@20MHz, accept true RS232 data, modify it, and resend as true RS232 as well as display on a 2x16 LCD module, it ran fine so I see no reason why the far more powerful PIC you're using won't do the job. During those 'early' years , I also had a Z80@4MHz run a complete computer (kbd, dsp, HD, as well as 3 serial ports), 8 ISRs, so 'speed' is not necessarily required. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19498
|
|
Posted: Wed Mar 14, 2018 11:13 am |
|
|
Let's put it into perspective.
I'm running a cellular modem at 57600, Bluetooth at 115200, writing to an SD, performing logarithmic conversions on the data, sampling the ADC every 5000th second, running an OLED display, and scanning a keyboard on a DsPic at 32MHz, and it still spends over 80% of it's time in the 'idle' part of the code....
A float32 multiply on a DsPIC at 120MHz, takes just 1.65uSec. The division though takes 8.32uSec. Still a lot better, but neither is exactly major.
Worth also adding that I hope the poster does realise that on the PIC24/30/33, the float32 already is an IEEE float. No conversion needed. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|