Android: Int()
Monkey Forums/Monkey Bug Reports/Android: Int()
| ||
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. |
| ||
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! |
| ||
Mark has said before that primary datatype casting is platform dependent. If you look around, this same error has been posted many times before. |
| ||
@eme64, http://monkeycoder.co.nz/Community/posts.php?topic=5745 |
| ||
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? |
| ||
Something like a textutils module that provides consistent conversions would be one approach +1 vote for textutils module. |
| ||
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 |
| ||
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. |
| ||
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. |
| ||
sounds like a candidate for a new String.ToInt method. maybe we can have one for floats too! |
| ||
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 conversionLocal tempStr:String = "123.456" Local tempFloat:Float = Float(tempStr) Local Result:Int = Int(tempFloat) |
| ||
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. |
| ||
Issue still present to-day on v84e. If something like this is possibleLocal 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? |
| ||
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... |