FloatToStr with more decimal places displayed ?

mikroC, mikroBasic and mikroPascal PRO for Microchip’s 8-bit PIC MCUs.
Author
Message
Soumitrab
Posts: 156
Joined: 08 Jan 2012 07:28

FloatToStr with more decimal places displayed ?

#1 Post by Soumitrab » 17 Jan 2023 16:39

Hi
The floattostr routine truncates the number of decimal places to 5 ... so if i want to display something like 0.00000011920928955 all i get is zero.
Is there a routine that can display a user-defined number of decimals ?

Thanks in advance

AntiMember
Posts: 136
Joined: 02 Jan 2020 19:00

Re: FloatToStr with more decimal places displayed ?

#2 Post by AntiMember » 19 Jan 2023 18:30

I think it would be faster to write your own function...

Soumitrab
Posts: 156
Joined: 08 Jan 2012 07:28

Re: FloatToStr with more decimal places displayed ?

#3 Post by Soumitrab » 19 Jan 2023 20:03

i thought so too and have a function ready, but its got a hitch that im unable to resolve. To get the fractional value i do this :

Code: Select all

procedure GetaStr(x: Real; var str: string[23] );
var
  w: Longint;
  tmp,frctn: Real;
begin
  w := Longint(x);

  Tmp := w * 1.0000000000;
  frctn:= x - Tmp;
..........
Now when x is 550.00011920928955, the value of fraction = 0.000122070 instead of 0.0001192092.
Any reasons ?

janni
Posts: 5373
Joined: 18 Feb 2006 13:17
Contact:

Re: FloatToStr with more decimal places displayed ?

#4 Post by janni » 19 Jan 2023 21:01

Soumitrab wrote:
19 Jan 2023 20:03
Now when x is 550.00011920928955, the value of fraction = 0.000122070 instead of 0.0001192092.
Any reasons ?
Yep - the finite size of floating-point number representation. mP uses only 32 bits to store floating-point number which corresponds to 7-7.5 digits accuracy. In other words, from your 14 digits after decimal point only 4 are reliably stored. Here are the numbers near yours that may be stored in 32-bit format used by mC:
550.000061035156
550.000122070313
550.000183105469
As you can see, the closest has exactly the fraction you've got. And keep in mind that when you do any calculations, the accuracy may drop further.

Soumitrab
Posts: 156
Joined: 08 Jan 2012 07:28

Re: FloatToStr with more decimal places displayed ?

#5 Post by Soumitrab » 20 Jan 2023 08:13

I Like the closest value. I am happy to use that and truncate the fractional value to 4-5 decimal places just for reporting (as in displaying).
Any ideas/tricks on how to extract and store the fraction as a separate 32bit dword ?

AntiMember
Posts: 136
Joined: 02 Jan 2020 19:00

Re: FloatToStr with more decimal places displayed ?

#6 Post by AntiMember » 20 Jan 2023 10:56

Maybe so:
procedure GetaStr(x: extended; var str: string[23] );
var
w: int64;
tmp,frctn: extended;
..........

janni
Posts: 5373
Joined: 18 Feb 2006 13:17
Contact:

Re: FloatToStr with more decimal places displayed ?

#7 Post by janni » 20 Jan 2023 13:52

Soumitrab wrote:
20 Jan 2023 08:13
Any ideas/tricks on how to extract and store the fraction as a separate 32bit dword ?
Storing the accurate fraction (if you meant that) isn't a problem. You may code it as a constant

Code: Select all

const frac=0.00011920928955;
Whether you can do something sensible with it, except displaying, is another matter.

If you already have a number converted to internal representation then there's no way to recover lost accuracy. You can extract the fraction as you did in your routine, but it won't be the accurate one.

Soumitrab
Posts: 156
Joined: 08 Jan 2012 07:28

Re: FloatToStr with more decimal places displayed ?

#8 Post by Soumitrab » 21 Jan 2023 09:15

In Delphi i can use the Extended type but thats not supported in MikroPascal.
AntiMember wrote:
20 Jan 2023 10:56
Maybe so:
procedure GetaStr(x: extended; var str: string[23] );
var
w: int64;
tmp,frctn: extended;
..........

Soumitrab
Posts: 156
Joined: 08 Jan 2012 07:28

Re: FloatToStr with more decimal places displayed ?

#9 Post by Soumitrab » 21 Jan 2023 09:19

What i meant is :
This loss of accuracy isnt worth displaying if its wrong. So is there a way to hack and extract the fractional part without subtracting the integer value and thereby storing the fractional part as an integer in a dword ?
Like just extract 11920928955 from 0.00011920928955; ?

Or better yet move to Pic32 - that supports int64 and extended.


janni wrote:
20 Jan 2023 13:52
Soumitrab wrote:
20 Jan 2023 08:13
Any ideas/tricks on how to extract and store the fraction as a separate 32bit dword ?
Storing the accurate fraction (if you meant that) isn't a problem. You may code it as a constant

Code: Select all

const frac=0.00011920928955;
Whether you can do something sensible with it, except displaying, is another matter.

If you already have a number converted to internal representation then there's no way to recover lost accuracy. You can extract the fraction as you did in your routine, but it won't be the accurate one.

janni
Posts: 5373
Joined: 18 Feb 2006 13:17
Contact:

Re: FloatToStr with more decimal places displayed ?

#10 Post by janni » 21 Jan 2023 16:07

Soumitrab wrote:
21 Jan 2023 09:19
What i meant is :
This loss of accuracy isnt worth displaying if its wrong. So is there a way to hack and extract the fractional part without subtracting the integer value and thereby storing the fractional part as an integer in a dword ?
Like just extract 11920928955 from 0.00011920928955; ?
The question is too general, I'm afraid. While one can store the integral and fractional parts in separate variables (assuming one knows the accurate value), there's not much that can be done with them within the available arithmetic libs. If you intend to preserve accuracy through some floating-point calculations, it most probably will not be possible. If you had in mind switching to integer arithmetic then in principle one may devise integer calculations with arbitrary precision, although this may be too demanding on processing time. Why don't you describe your problem in some detail?
Or better yet move to Pic32 - that supports int64 and extended.
Extended type in mE compilers for PIC32 means in fact double precision (while type double and real are equivalent and of single precision). Last time I checked (years ago, though) there were some problems with the double precision type but hopefully that changed.


Soumitrab
Posts: 156
Joined: 08 Jan 2012 07:28

Re: FloatToStr with more decimal places displayed ?

#12 Post by Soumitrab » 23 Jan 2023 06:13

Problem is very simple - i want to convert a floating point value to a string but that conversion is typically limited to 5 decimal places in the FloatToStr routine and so i thought of having a custom routine to show more decimal places.
janni wrote:
21 Jan 2023 16:07
Why don't you describe your problem in some detail?

Soumitrab
Posts: 156
Joined: 08 Jan 2012 07:28

Re: FloatToStr with more decimal places displayed ?

#13 Post by Soumitrab » 23 Jan 2023 06:16

Thats a nice web app, the compiler has a similar function built-in too though.

janni
Posts: 5373
Joined: 18 Feb 2006 13:17
Contact:

Re: FloatToStr with more decimal places displayed ?

#14 Post by janni » 23 Jan 2023 16:29

Soumitrab wrote:
23 Jan 2023 06:13
Problem is very simple - i want to convert a floating point value to a string but that conversion is typically limited to 5 decimal places in the FloatToStr routine and so i thought of having a custom routine to show more decimal places.
I can only repeat: if you already have a number converted to internal representation then there's no way to recover lost accuracy. Only if the exact number comes from another source (like externally coded double precision) one may write a conversion to string preserving it's accuracy.

AntiMember
Posts: 136
Joined: 02 Jan 2020 19:00

Re: FloatToStr with more decimal places displayed ?

#15 Post by AntiMember » 23 Jan 2023 17:39

I think it's easier to upgrade to a more powerful processor. Writing a float transformation is not at all an easy task.

Post Reply

Return to “PIC PRO Compilers”