Android: Int()

Monkey Forums/Monkey Bug Reports/Android: Int()

eme64(Posted 2013) [#1]
I had some issues and finally found out that it is because of Int()
And the problem only occours with Android, not with HTML5.

Code:

Import mojo

Class Game Extends App
    Method OnCreate:Int()
    	
		Return true
    End Method
    
    
	Method OnUpdate:Int()
		
		Return True
	End method
	
	Method OnRender:Int()
		Cls(0,255,255)
		
		Local float_value:float = 123.456
    		Local string_value:String = String(float_value)
    		Local int_value = Int(string_value)
    		
    		SetColor(255,0,0)
    		DrawRect(0,0,int_value,30)
		
		Return true
	End Method
End class

Function Main:Int()
	
	New Game()
	
	Return true
End Function



HTML5 has no problem converting "123.456" into 123.
Android however just ends the app.

I am using version 74a

Thanks for helping.


eme64(Posted 2013) [#2]
What I forgot to mention: converting "123" into 123 by Int() works just fine.
So I think it must be the "." that makes trouble here.

Edit: Because my One X had recently an update I had to find the debug-settings. Now I got the error in the Debug-Log:

I/[Monkey]( 2139): Monkey Runtime Error : Invalid int: "123.456"

It is just ugly when errors occour with some platform but not with an other.
But I must say, Monkey is really cool!


Goodlookinguy(Posted 2013) [#3]
Mark has said before that primary datatype casting is platform dependent. If you look around, this same error has been posted many times before.


programmer(Posted 2013) [#4]
@eme64, http://monkeycoder.co.nz/Community/posts.php?topic=5745


marksibly(Posted 2013) [#5]
I am going to have a look at doing something about this soon-ish, as it keeps tripping people up.

My main concern is speed - the 'built in' string->number ops are likely to be faster than custom code, esp. in Java/C#.

Something like a textutils module that provides consistent conversions would be one approach, but perhaps it wouldn't matter if language conversions were a little bit slower?


programmer(Posted 2013) [#6]
Something like a textutils module that provides consistent conversions would be one approach
+1 vote for textutils module.


Erik(Posted 2013) [#7]
Perhaps cstranslator should generate

int.Parse(XX, CultureInfo.InvariantCulture)

instead of int.Parse(XX)

int.Parse does a lot, custom code that do less would probably be a lot faster, see http://www.dotnetperls.com/int-parse-optimization


Gerry Quinn(Posted 2013) [#8]
Converting strings to numbers shouldn't be something people are doing a lot I reckon (unless it's some kind of text reading app), so I don't suppose speed would be an issue.

If there's just the one bug, maybe just searching for invalid characters in Android strings and fixing as appropriate would be enough.


Erik(Posted 2013) [#9]
Global DecimalSeparator = "."[0]

Function StrToInt(str:String)
  Local res = 0
  Local negative?

  For Local i := 0 Until str.Length
    Local char = str[i]
    If char="-"[0] Then
      negative = True
      Continue
    End
    If char=DecimalSeparator Exit

    If char<"0"[0] Continue
    If char>"9"[0] Continue
    res = 10 * res + (char - 48)
  End

  If negative Return -res
  Return res
End


This function don't crash and is around 50 times faster than Int() in C#
, about 3 times faster in GLFW and about 2 times faster in HTML. I haven't tested any other targets.


Nobuyuki(Posted 2013) [#10]
sounds like a candidate for a new String.ToInt method. maybe we can have one for floats too!


Deen(Posted 2014) [#11]
i've bumped into this issue yesterday when trying to port my apps into android. i read from a txt file which contains level positioning data. so what i do is stages of conversion

Local tempStr:String = "123.456"
Local tempFloat:Float = Float(tempStr)
Local Result:Int  = Int(tempFloat)



ziggy(Posted 2014) [#12]
I would suggest the contrary. Make the built-in string-numeric parser consistent between targets even if it's a bit slower and provide a separated native conversor for the rare situations where speed is very important.
Most of the time you want this conversion reliable between targets and only very occasionaly (if ever) you need it to perform at native speed, which should be very close to a regular parsing implementation or even slower if your considering culture notations on the target native platform.


itto(Posted 2015) [#13]
Issue still present to-day on v84e. If something like this is possible

Local tempStr:String = "123.456"
Local tempFloat:Float = Float(tempStr)
Local Result:Int  = Int(tempFloat)


then it's obvious one would expect this to work too

Local Result:Int = Int("123.456")


especially since it works in some languages natively. Especially considering it affects the Android target, which requires compilation every time and to check the logcat or similar to spot the error. It's a PITA.

Considering conversions naturally require some operations to complete, programmers know this should be done when there's time to spare (i.e. during loading and when setting up things), not in real-time (even though I suspect they would happen so sparingly it wouldn't be an issue anyway).

I think for a product aiming at coding once and run the same on all targets, basic things like this should definitely be consistent across targets.

What about leaving all the unaffected targets like this, and just add the required code to the Android and other affected targets, which does the middle-way float conversion for us automagically?


marksibly(Posted 2015) [#14]
I've loathed 'fixing' this because it would make int AND float (which I'd have to do too for completeness) conversions considerably slower, and definitely entering the territory of 'I wouldn't do that in my own code'.

However, there is a very simple fix which this which for some reason hasn't occurred to me until now - native code! So, fix coming soon...