• Welcome to Powerbasic Museum 2020-B.
 

News:

Forum in repository mode. No new members allowed.

Main Menu

FORMAT$ any faster option

Started by Eros Olmi, June 21, 2007, 06:13:57 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Eros Olmi

I need to speed up operation using PB FORMAT$ function.
I have a loop that need to convert many, many numbers to strings. So far I was using FORMAT$(xResult, 18)  where xResult is EXT type (mandatory). I was wondering if there is something faster.
I've found this post on PB forum but seems to deal with LONG type only: http://www.powerbasic.com/support/forums/Forum6/HTML/001627.html

Thanks a lot
Eros
thinBasic Script Interpreter - www.thinbasic.com | www.thinbasic.com/community
Win7Pro 64bit - 8GB Ram - Intel i7 M620 2.67GHz - NVIDIA Quadro FX1800M 1GB

Donald Darden

There are at least four methods for converting numbers from one base to another.
Using integer division by ten is one of the best and fastest, even though division
is not exactly fast.  Two methods involve the use of powers, which is even
slower, and another involves multiplication, but is not well suited here.

You do not give a range of values or the degree of accuracy involved.  For instance, whether your extended floating point type involves any fractions or not.
This would determine if you could first convert the present type to a large
integer, say a quad or currency value first.  Then the integer divide step would
be applicable,

FORMAT$() or USING$() both have a lot of work to do, such as determining the
pattern of the decimal results.  You can avoid that if you can do without the
added formatting.  For instance, you can convert the number to a string with
STR$(), then left-pad the resulting string with spaces.  In fact, you can define a fixed length string and use RSET$() and STR$() to create a right-aligned string
value that can be printed as-is, but without any commas or decimal place.

Eros Olmi

Donald,

yes, I have a general idea of the hard work FORMAT$ have to do.
I asked about FORMAT$ optimization because I use a lot inside thinBasic interpreter when converting numeric expressions to string expressions in all case script mix them.

For example an epxression like: MyString = "ABCD" & 234 & "-" & sin(x)
is perfectrly valid in thinBasic and produce a correct string without the need to use STR$ or whatever. One of the ideas behind thinBasic is the less code the better for the user.

But to do that thinBasic internally has to do the job of converting numeric expression to strings thoudands of times per seconds (if not even more).

So I was wondering if there is a faster way rather than using FORMAT$.
Numeric Ranges? Any range suitable in an EXTENDED variable.
Precision: 18 digits (if any)

I tried STR$ but it is slower that FORMAT$ due to the time to LTRIM it. I do not want the left space. The user have to choose if add a space or not. Space in STR$ is more an hystorical matter rather than a useful option.

So I use FORMAT$ because it is the fastest way I've found using native PB functions. But I do not need the formatting facilities of FORMAT$ because I always use FORMAT$(MyEXTNumber, 18) so I'm pretty sure there should be  a faster way.

Thanks
Eros
thinBasic Script Interpreter - www.thinbasic.com | www.thinbasic.com/community
Win7Pro 64bit - 8GB Ram - Intel i7 M620 2.67GHz - NVIDIA Quadro FX1800M 1GB

Charles Pegge


Eros, this might do the job about 3.5 times to 7 times faster than FORMAT$ with some limitations. ( No E notation). Also, Freebasic does not support extended precision in 0.16b, but PowerBasic does.

There are a few 'experiments ' left in the source code but thay have been commented out. In general, the less code the better. The x87 takes over 140 clocks to do the packed BCD conversion so that is the ultimate limiting factor.

http://www.jose.it-berater.org/smfforum/index.php?topic=986


Eros Olmi

Charles,

thanks a lot for your effort. I will check the code and see if I can insert into thinBasic.
From a first sight, I have the impression I need to add a LEFT$ to get the real string from the allocated buffer after FFormat function is executed.
Anyhow I will give you back.

Thanks again
Eros
thinBasic Script Interpreter - www.thinbasic.com | www.thinbasic.com/community
Win7Pro 64bit - 8GB Ram - Intel i7 M620 2.67GHz - NVIDIA Quadro FX1800M 1GB

Charles Pegge

You wont need a LEFT$, I've done that for you in the latter half of the function. The only extra work is to pick up the string from the buffer after the fformat is called, since this returns the length only. thus:

length=ffunction( varptr(num), dp, bufferptr )
textnumber=mid$(buffer, 97, length)

for a small overhead this could be wrapped in a basic function using a global buffer and bufferptr. But I dont know how expensive it is to create a new string for the textnumber every time. It could be significant.


function ffmt( num as double, dp as long) as string
local length as long
length=ffunction( varptr(num), dp, bufferptr )
function=mid$(buffer,97,length)
end function



end function

Eros Olmi

Sorry Charles but I missed to read "MAP OF WORKSPACE" indications and thought string buffer was used only by returning string.
Now it is clear.
thinBasic Script Interpreter - www.thinbasic.com | www.thinbasic.com/community
Win7Pro 64bit - 8GB Ram - Intel i7 M620 2.67GHz - NVIDIA Quadro FX1800M 1GB