Reality Check

BlitzMax Forums/BlitzMax Beginners Area/Reality Check

dw817(Posted 2016) [#1]
Getting perfectly accurate visual results for Real Numbers is a bit of a pain in BlitzMAX.

Going across some archives I saw someone had written a routine to display real numbers with pretty high accuracy. It's not perfect, try to get too specific and it will make inaccurate visual results just like BlitzMAX.

But it's certainly better than what is provided !




grable(Posted 2016) [#2]
You can also use libc sprintf family of functions for this, which is what blitzmax uses for float->string too.
Though its not as fast as yours, its probably correct in all cases.
Function ftos:String( v:Double, d:Int)
	Extern "C"
		Function sprintf:Int( p:Byte Ptr, fmt$z, d:Int, v:Double)
	EndExtern
	Local buf:Byte[256]
	Local sz:Int = sprintf( buf, "%.*f", d, v)
	Return String.FromBytes( buf, sz)
EndFunction

C version to tighten the gap somewhat.
#include <brl.mod/blitz.mod/blitz.h>

BBString* ftos( double v, int d) {
	char buf[256];
	int sz = sprintf( buf, "%.*f", d, v);
	BBString* str = (BBString*)bbGCAllocObject( sizeof(BBString)+ sz *sizeof(BBChar), &bbStringClass, BBGC_ATOMIC);
	str->length=sz;
	for( int i=0; i<sz; i++) str->buf[i] = buf[i];
	return str;
}

My measurements (in milliseconds)
roff=8
c_ftos=12
bmx_ftos=18



dw817(Posted 2016) [#3]
Beautiful work, Grable. I'm not understanding how you would code the C version, but the BMX_FTOS works just fine ! Here's a grueling test for it.



Nicely done, Grable !!

Just for instance though, if you change those 2 17s to 19, it will get inaccurate results.

Testing QBasic.
FOR I=0 TO 19 STEP 1/19
  PRINT USING("####.####");I
NEXT
Ah ha ! Guess who can't keep up ! I tried the 19 in QBasic and it gives the wrong results with Print Using for the final number ... so there is a limit to accuracy in real. I was beginning to wonder.

It does, however, do the 17, just as yours does with no problems.

BTW, Casaber was looking for this kind of output accuracy too. So you definitely helped out 2 people today on this !


grable(Posted 2016) [#4]
Happy to help :)

For the C version, you would need MinGW installed as it has to be compiled. Putting it in a file and doing the below is possible then.
Import "ftos.c"
Extern "C"
	Function ftos:String( v:Double, d:Int)
EndExtern

Or if you already have another C compiler, you could import the object file directly.


dw817(Posted 2016) [#5]
Ouch. Way over my head, Grable.

I do know when I used PRINT USING in my code, I wrote a formidable checks and balance program in QBasic. Now that I got DOS BOX and QB working again, it's nice to be able to refer to my older programs, including that, again.

Don't know if there's too much need for a checkbook program in BlitzMAX these days what with the massive amount of Freeware apps already out there.

Ultimately I do want to write the perfect original program that everyone finds useful and unique. Likely I am not alone in this quest. :)