Recent

Author Topic: FloatToStr issue  (Read 591 times)

J-G

  • Hero Member
  • *****
  • Posts: 1055
FloatToStr issue
« on: June 03, 2026, 01:01:42 pm »
A little while ago I had an issue with formatting when I wanted to replace the decimal point with a 'Centre dot'  -  [·]  -  @WP kindly pointed me in the right direction and I've now expanded my modified FloatToStr Function to also strip trailing zeros etc.

Today I came across a 'corollary' that I thought worth reporting back on.

I often wish to separate the Integer part of a number from the decmal part and for that I look for the decimal point  - using  p = Pos('.',S) and then copy(S,1,p-1) & Copy(S,p+1,L)   -  When I came to do this after changing to '·' I found that the second 'copy' returned a string with a '?' at the start.    -   after a little scratching of the head, I realised that the 'centre dot' is a two byte character so the 'Copy' routine quite correctly takes the extra character to be its start.   %)

Changing p+1 to p+2 sorted it.

Hopefully this feedback will be beneficial to anyone who happens to come across the previous discussion  :)

FPC 3.0.0 - Lazarus 1.6 &
FPC 3.2.2  - Lazarus 2.2.0 
Win 7 Ult 64

paweld

  • Hero Member
  • *****
  • Posts: 1644
Re: FloatToStr issue
« Reply #1 on: June 03, 2026, 01:19:05 pm »
If you suspect that the string may contain non-ASCII characters, the best approach is to use UTF8Copy, UTF8Length and UTF8Pos from the LazUTF8 module
Best regards / Pozdrawiam
paweld

Xenno

  • Full Member
  • ***
  • Posts: 111
    • BS Programs
Re: FloatToStr issue
« Reply #2 on: June 03, 2026, 01:25:33 pm »
Alternative:

Code: Pascal  [Select][+][-]
  1. var
  2.   SL: TStringList;
  3.  
  4.   ...
  5.   SL.Text := StringReplace(S, '·', #13, [rfReplaceAll];
  6.   str1 := SL[0];
  7.   str2 := SL[1];

Maybe slower.
Lazarus 4.0, Windows 10, https://www.youtube.com/@bsprograms

J-G

  • Hero Member
  • *****
  • Posts: 1055
Re: FloatToStr issue
« Reply #3 on: June 03, 2026, 01:30:50 pm »
Thanks for that insight @paweld  -  I don't do enough programming to think about what I would consider 'exotic' routines  :D   but it's certainly worth raising the point.


FPC 3.0.0 - Lazarus 1.6 &
FPC 3.2.2  - Lazarus 2.2.0 
Win 7 Ult 64

paweld

  • Hero Member
  • *****
  • Posts: 1644
Re: FloatToStr issue
« Reply #4 on: June 03, 2026, 02:55:51 pm »
@Xenno - If that's what you want to do, a faster and more elegant solution is to use TStringArray:
Code: Pascal  [Select][+][-]
  1. var
  2.   sarr: TStringArray;
  3. begin
  4.   sarr := S.Split(['·']);
  5.   str1 := sarr[0];
  6.   if Length(sarr) > 1 then
  7.     str2 := sarr[1];
  8. end;
  9.  
« Last Edit: June 03, 2026, 02:58:39 pm by paweld »
Best regards / Pozdrawiam
paweld

Zvoni

  • Hero Member
  • *****
  • Posts: 3399
Re: FloatToStr issue
« Reply #5 on: June 03, 2026, 03:18:29 pm »
@Xenno - If that's what you want to do, a faster and more elegant solution is to use TStringArray:
Code: Pascal  [Select][+][-]
  1. var
  2.   sarr: TStringArray;
  3. begin
  4.   sarr := S.Split(['·']);
  5.   str1 := sarr[0];
  6.   if Length(sarr) > 1 then
  7.     str2 := sarr[1];
  8. end;
  9.  

and remember, to never ever assign the fractional part to an Integer-Variable......  :P
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

Xenno

  • Full Member
  • ***
  • Posts: 111
    • BS Programs
Re: FloatToStr issue
« Reply #6 on: June 03, 2026, 04:28:20 pm »
@Xenno - If that's what you want to do, a faster and more elegant solution is to use TStringArray:
Code: Pascal  [Select][+][-]
  1. var
  2.   sarr: TStringArray;
  3. begin
  4.   sarr := S.Split(['·']);
  5.   str1 := sarr[0];
  6.   if Length(sarr) > 1 then
  7.     str2 := sarr[1];
  8. end;
  9.  

Thank you, @paweld. That's new for me.
Lazarus 4.0, Windows 10, https://www.youtube.com/@bsprograms

J-G

  • Hero Member
  • *****
  • Posts: 1055
Re: FloatToStr issue
« Reply #7 on: June 03, 2026, 06:37:34 pm »
@Xenno - If that's what you want to do, a faster and more elegant solution is to use TStringArray:
Code: Pascal  [Select][+][-]
  1. var
  2.   sarr: TStringArray;
  3. begin
  4.   sarr := S.Split(['·']);
  5.   str1 := sarr[0];
  6.   if Length(sarr) > 1 then
  7.     str2 := sarr[1];
  8. end;
  9.  

Hmmm . . .  Whilst that option looks interesting, regrettably I cannot fully understand it  :-[

I can appreciate that it could be used to split any string that contains a decimal point and I have to assume that I could equally specify the 'Centre dot' but I cannot fathom where/how Str1 and Srt2 are declared ??   or why there is a test for the length of Sarr  ??

. . . .  this is after some research and viewing of the FreePascal Manual  :(

I'd appreciate some further explanation.
FPC 3.0.0 - Lazarus 1.6 &
FPC 3.2.2  - Lazarus 2.2.0 
Win 7 Ult 64

Thausand

  • Hero Member
  • *****
  • Posts: 560
Re: FloatToStr issue
« Reply #8 on: June 03, 2026, 07:17:57 pm »
I'd appreciate some further explanation.
Split is take string and make return array of string when is see ".". So when is 1 "." then is return 2 string. When 2 x "." in string then is return 3 string.

All string that 'break' is store in tstringarray. TStringArray is array of string. This dynamic array and can copy when use index 0..n and return type string.

Code: Pascal  [Select][+][-]
  1. var
  2.   str1, str2: string;
  3.  
A docile goblin always follow HERMES.md

paweld

  • Hero Member
  • *****
  • Posts: 1644
Re: FloatToStr issue
« Reply #9 on: June 03, 2026, 07:35:54 pm »
Quote from: J-G
I cannot fathom where/how Str1 and Srt2 are declared ??
I based this on @Xenno's example (which uses such variables), so I just modified his code.
Quote
why there is a test for the length of Sarr  ??
because if you specify an array index that is out of range, you will get an error

the Split helper allows you to specify multiple separators: https://www.freepascal.org/docs-html/rtl/sysutils/tstringhelper.split.html
as well as skipping empty strings: https://www.freepascal.org/docs-html/rtl/sysutils/tstringsplitoptions.html
Best regards / Pozdrawiam
paweld

J-G

  • Hero Member
  • *****
  • Posts: 1055
Re: FloatToStr issue
« Reply #10 on: June 03, 2026, 07:44:47 pm »
Thanks again for the further explanation (and links)  -  it now makes a lot more sense  :-[

However !!  -  I did actually fathom what was going on and have incorporated [Split] into my code very effectively  -  Of course it works with the centre dot, and is much more elegant that my existing splitting routine.

I good day has been had  ;D
FPC 3.0.0 - Lazarus 1.6 &
FPC 3.2.2  - Lazarus 2.2.0 
Win 7 Ult 64

Khrys

  • Sr. Member
  • ****
  • Posts: 458
Re: FloatToStr issue
« Reply #11 on: June 04, 2026, 07:51:28 am »
I often wish to separate the Integer part of a number from the decmal part [...]

Note that there's also  Int  and  Frac  which do exactly[1] this without involving stringification at all.

[1] Well, not quite exactly - floating-point precision issues can lead to ever so slightly different results.

J-G

  • Hero Member
  • *****
  • Posts: 1055
Re: FloatToStr issue
« Reply #12 on: June 06, 2026, 12:06:38 am »
Thanks for the further input @Khrys  -  I know I'm late responding but I've had a day off Pascal as I needed to set some music. I'll be back tomorrow (I think  :-\)

I am (of course) familiar with Int & Frac and do use them on occasion (much more 'Int') but in this particular case I'm actually dealing with 'Strings' rather than 'Numbers'.

When I started programming for 'Windows' (as opposed to DOS) one of the biggest hurdles I had to overcome was the fact that to display numbers on screen they HAD to be strings. That was a big learning curve :)

FPC 3.0.0 - Lazarus 1.6 &
FPC 3.2.2  - Lazarus 2.2.0 
Win 7 Ult 64

 

TinyPortal © 2005-2018