[Solved] Possible bugs in bbStringFromInt and bbStringFromLong

BlitzMax Forums/BlitzMax Programming/[Solved] Possible bugs in bbStringFromInt and bbStringFromLong

grable(Posted 2017) [#1]
Didnt know where else to put this, since it seems the bug forum is locked, so here it goes ;)

There is a conversion bug in bbStringFromInt and bbStringFromLong, the main functions used to convert numbers to strings in bmx.
The bug only triggers with one specific value, the lowest possible negative value. Even though there is a check for this it never triggers.
The suggested fix is to check for this number directly instead of the current way of negating a negative value and checking if its still negative.

Sample to show the bug:
Framework BRL.StandardIO
Import BRL.Retro

SuperStrict

PrintInt -2147483648
PrintLong -9223372036854775808:Long

Extern "C"
	Function printi( fmt$z, a:Int) = "printf"
	Function printl( fmt$z, a:Long) = "printf"
EndExtern

Function PrintInt( val:Int)
	Print "            hex: " + Hex(val)
	Print "            bin: " + Bin(val)
	printi( "  printf-signed: %d~n", val)
	printi( "printf-unsigned: %u~n", val)
	Print "bbStringFromInt: " + val
	Print
EndFunction

Function PrintLong( val:Long)
	Print "             hex: " + LongHex(val)
	Print "             bin: " + LongBin(val)
	printl( "   printf-signed: %lld~n", val)
	printl( " printf-unsigned: %llu~n", val)
	Print "bbStringFromLong: " + val
	Print
EndFunction

Suggested fixes to brl.mod/blitz.mod/blitz_string.c:
BBString *bbStringFromInt( int n ){
	char buf[64],*p=buf+64;
	int neg=n<0;
	if( neg ){
		if( n == -2147483648 ) return bbStringFromBytes( "-2147483648",11 );
		n=-n;
	}
	do{
		*--p=n%10+'0';
	}while(n/=10);
	if( neg ) *--p='-';
	return bbStringFromBytes( p,buf+64-p );
}

BBString *bbStringFromLong( BBInt64 n ){
	char buf[64],*p=buf+64;
	int neg=n<0;
	if( neg ){
		if( n == -9223372036854775808L ) return bbStringFromBytes( "-9223372036854775808",20 );		
		n=-n;
	}
	do{
		*--p=n%10+'0';
	}while(n/=10);
	if( neg ) *--p='-';
	return bbStringFromBytes( p,buf+64-p );
}



col(Posted 2017) [#2]
I already get the correct values for signed int and signed long.
What values are you getting?

Executing:untitled1.exe
            hex: 80000000
            bin: 10000000000000000000000000000000
  printf-signed: -2147483648
printf-unsigned: 2147483648
bbStringFromInt: -2147483648

             hex: 8000000000000000
             bin: 1000000000000000000000000000000000000000000000000000000000000000
   printf-signed: -9223372036854775808
 printf-unsigned: 9223372036854775808
bbStringFromLong: -9223372036854775808



LT(Posted 2017) [#3]
Bugs are to be reported on Github now.

http://www.blitzbasic.com/Community/posts.php?topic=107218


grable(Posted 2017) [#4]
Oh, sorry. Forgot to add the result hehe
Ah, didnt think about github, il look into it if this really is a bug.

This is what i get with vanilla..
            hex: 80000000
            bin: 10000000000000000000000000000000
  printf-signed: -2147483648
printf-unsigned: 2147483648
bbStringFromInt: -./,),(-*,(

             hex: 8000000000000000
             bin: 1000000000000000000000000000000000000000000000000000000000000000
   printf-signed: -9223372036854775808
 printf-unsigned: 9223372036854775808
bbStringFromLong: -'..--).0-*(+,))+(0(


But if you get correct results maybe theres something wrong on my end :(
Just to test, what do you get for the same numbers but positive instead?


col(Posted 2017) [#5]
what do you get for the same numbers but positive instead?

I get the exact same results as negative numbers, using the legacy compiler 1.50 - MinGW 4.7.1

Looks like it might be your setup?


Derron(Posted 2017) [#6]
Results seem correct here too (Linux, 1.50).


bye
Ron


grable(Posted 2017) [#7]
Yeah, looks to be on my end then.

Weird thing is ive had it for years too, through multiple mingws (currently at 5.1.0). Just didnt run into it that often so didnt matter that much.

Ah well.. Il keep my fix but others can ignore this.

Thanks for the help guys :)


Brucey(Posted 2017) [#8]
It is definitely a bug.

This is how I solved the problem in NG :
BBString *bbStringFromInt( int n ){
	char buf[64];

	sprintf(buf, "%d", n);

	return bbStringFromBytes( buf, strlen(buf) );
}

BBString *bbStringFromLong( BBInt64 n ){
	char buf[64];

	sprintf(buf, "%lld", n);

	return bbStringFromBytes( buf,strlen(buf) );
}



Derron(Posted 2017) [#9]
And which one is longer faster?

And why does it only happen to certain users / in certain circumstances ? (just asking for some elaboration/explaining - to learn something)


bye
Ron