June 15, 2024, 11:07:49 PM

News:

Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........


str$ query

Started by Zen, January 10, 2006, 09:58:05 AM

Previous topic - Next topic

0 Members and 2 Guests are viewing this topic.

Zen

I know it has already been changed once but would it be possible to have the str$ function have no decimal places by default rahter than 2 as i believe more people will use it without the decimal places than with them unless they are performing math operations. I have used no end of times and every time have to put the optional 0 in.

If its only me using it like this then nevermind. ;)

Lewis

Ionic Wind Support Team

Sounds like a good change.  Any objections?
Ionic Wind Support Team

ThadMiller

My preference would be that str$ would return as many decimal places as the number contains.  str$(1.2345678) should return "1.2345678" while str$(8.9) would return "8.9".  But that's just my opinion.  :)

-Thad

Parker

I don't think that's very possible, since the number 1.0000000 contains 7 decimal places, 1.0 contains 1, but they're both the exact same. I suppose there could be a "trim zeroes" function though.

I like the option of having 0 decimal places by default though.

Bruce Peaslee

January 10, 2006, 02:35:04 PM #4 Last Edit: January 10, 2006, 04:28:36 PM by peaslee
No objection. Don't forget the function Using() for extra formatting.
Bruce Peaslee
"Born too loose."
iTired (There's a nap for that.)
Well, I headed for Las Vegas
Only made it out to Needles

Steven Picard


Zen

Good Good, its being buggin me for a while that. Glad its not just me.

Lewis

ThadMiller

I guess I just have a weird feeling about str$(1.456) returning "1", but it seems I'm the only one.  :)

So long as there is some sort of workaround.  For example, in doing database queries, the SQL query is a string.  If you have a float data type, you might want to do something like this...

sql = "select * from inventory where unitcost > " + str$(somevalue)

In this case, unitcost would be the float value, so you wouldn't necessarily know the number of decimal places of somevalue, but you would want the query to be accurate (maybe cost is a bad example, because you would rarely go below 4 decimal places, but you get the idea).  I'm sure there are other examples, and I'm sure there are work-arounds... but I'm looking for simplicity.  (maybe I'm one that should stick with BASIC)  ;)

-Thad

Parker

The way IBasic handled those is an ANYTYPE which was 64 bit and contained the actual variable and a constant that told what type it was, so you could choose whether or not it was an integer or float, string, double, uint, pointer, UDT, etc. I don't think the Aurora compiler knows this information, except maybe the NEW() function.

I guess you just have to make sure you pass an optional parameter if you want it a float. Now if we had overridden functions... ;)

Ionic Wind Support Team

Thad,
Were just taking about changing the default, not removing the capability of displaying decimal places.

In IBasic you have to use SetPrecision to specify the number ahead of time.  It defaulted to 2 so I made STR$ default to 2.  STR$ in Aurora has the optional parameter.

STR$(num, 10);

Displays 10 decimal places.  In IBasic you had to do:

SETPRECISION 10
STR$(num);

There is nothing in IBasic or Aurora that automatically calulcates the proper number to display. It is up to you in both languages to chose the precision.

Paul.
Ionic Wind Support Team

Parker

QuoteIn IBasic you have to use SetPrecision to specify the number ahead of time.

... or
extern _print_prec
_print_prec = 0 /* Same as SETPRECISION(0) */


sorry, just had to mention it. It's nice to see how everything works.

ThadMiller

Quote from: Ionic Wizard on January 10, 2006, 05:57:50 PM
There is nothing in IBasic or Aurora that automatically calulcates the proper number to display. It is up to you in both languages to chose the precision.

I suppose I was referencing the behavior of my native language of VB, where CStr(1) returns "1", CStr(1.234) returns "1.234", and CStr(1.234E-23) returns "1.234E-23".  That functionality gives an actual representation of the number as a string so it can be used in things like SQL queries.

I know the trick in FORTRAN to convert numbers to strings, is to actually print to the read buffer - or read from the print buffer (however you want to look at it)... would something like that work?  Ex: myStringVal = read(printf("\f",myFloatVal))

Sorry for being a pain - I really seem to be going against the grain here.  ;)

-Thad

Parker

I don't think STR$ will end up doing that, but feel free to write your own function. MS spent a lot of time making VB easy to use, but sometimes it's better to learn the actual concepts involved before moving to libraries like that. I've learned that from the API.

Ionic Wind Support Team

Functions like that have a lot of overhead, which is probably why languages like C don't include one.  Not something you would want to use in a financial app of any kind.

There are a few ways to do it.  The first involves multiplying until you get to repeating zero results.  The second involves converting to a string first with max precision (8 or 16 decimal places for float or double) and scanning the string fo repeating zero results.  Floating point processors, such as intels, have limited precision in representing decimal numbers that don't fit evenly into negative powers of two.  So it is very common to end up with a result like:

1.00000000123

So when writing a true floating point number to string function you'll need to take this into account.  And pick a finite vale for your repeating zero test.

Ionic Wind Support Team

Ionic Wind Support Team

Here is an example of both ways.  One uses a string, the other mathematical operations. Change the constant ZERO_CROSS to 4 to see what happens.




global sub main()
{
writeln(conv2(1)+"\n");
writeln(conv2(1.234)+"\n");
writeln(conv2(1.0000385)+"\n");
writeln(conv2(.00765)+"\n");
writeln(conv2(103.1100022)+"\n");

while GetKey() = "";
}

#define ZERO_CROSS 5
sub conv(double num),string
{
string test = str$(num,15);
int pos = instr(test,".");
int zc = 0,places = 0;
int save = pos;
int last = pos;
while((zc < ZERO_CROSS) AND test[pos])
{
if(test[pos] = "0")
{
zc++;
}
else
{
zc = 0;
last = pos+1;
}
pos++;
}
places = last-save;

return STR$(num,places);
}

sub conv2(double num),string
{
double hold = num;
int64 test;
int pos = 0;
int last = 0;
int zc = 0;
while(zc < ZERO_CROSS)
{
//get the whole number portion
test = hold;
//subtract it
hold -= test;
//get the next digit to test
hold *= 10.0;
test = hold;
if(test = 0)
{
zc++;
}
else
{
last = pos+1;
zc=0;
}
pos++;
}

return STR$(num,last);
}


Ionic Wind Support Team

ThadMiller

I understand the overhead as well as issues with exact values.  That's exactly why the money data type exists in things like MS SQL Server, it's fixed at 4 decimal places.  Anyone that deals with databases knows (or should know anyway) that you won't get any results with a query like "where myValue=1.4" if myValue is a float, no matter how many 1.4 values you actually have in the database (it will most likely be 1.400001xxx).  Float data types, in general, are something you never want to use in any financial app... they're simply not exact (use decimal instead).  But now I'm just going off on a tangent...

I don't know what the number is, but I imagine there's an actual number of digits that are considered to be precise.  Whether that would be CPU dependant, OS dependant, or language dependant, I don't know... but it can probably be googled.  At that point, you round the last precise digit (because you might have 1.39999987) and trim trailing zeros.  Maybe when life settles down, I'll look into writing a function... expect to hear from me again in about 40 years.  ;)

-Thad

Ionic Wind Support Team

Look back a post ^^

Already wrote it for you.
Ionic Wind Support Team

John S

my $0.02

It would be nice to have str$() yield matching results (i.e.:  str$(1.123) returns "1.123", str$(1.123456) returns "1.123456" ).
John Siino, Advanced Engineering Services and Software

Zen

Hmm i think that str$ returning the actual number of decimal places inputed is popular. Doing it this way would seem to satisfy more people, including myself as, if i just entered str$(1) it should return 1 and not 1.00 like it has been doing. You could still have the optional peramater to set the number of decimal places.

What say yee Paul?

Lewis

LarryA

Quote from: Lewis on January 11, 2006, 05:37:14 AM
Hmm i think that str$ returning the actual number of decimal places inputed is popular. Doing it this way would seem to satisfy more people, including myself as, if i just entered str$(1) it should return 1 and not 1.00 like it has been doing. You could still have the optional peramater to set the number of decimal places.

What do you need str$ for if it works like that?

PRINT "1.234"

... accomplishes that.

str$ is almost always supplied with a variable to digest, and as the variable type willl most often supply more decimal places than you'd want to display, a formatting decision is to be made.  I might even make an argument for making the decimal places parameter mandatory... particularly if, as I understand it, there is not a modal value like SETPRECISION to dictate the format.
"Aerodynamics are for people who can't build engines." -- Enzo Ferrari
"Turbochargers were for people who can't build engines" -- Keith Duckworth

Ionic Wind Support Team

Did anyone read my example code?  Last post on the first page of this topic.


sub conv2(double num),string
{
double hold = num;
int64 test;
int pos = 0;
int last = 0;
int zc = 0;
while(zc < ZERO_CROSS)
{
//get the whole number portion
test = hold;
//subtract it
hold -= test;
//get the next digit to test
hold *= 10.0;
test = hold;
if(test = 0)
{
zc++;
}
else
{
last = pos+1;
zc=0;
}
pos++;
}

return STR$(num,last);
}


Ionic Wind Support Team