AdmiralAlkex Posted December 8, 2011 Posted December 8, 2011 If I wrote a piece of code and you decide to change it... you need to pay attention. I write code that takes scope into account. This was a case where somebody didn't notice the scope a variable needed to be in.I made a mistake. I will fix on weekend. .Some of my scripts: ShiftER, Codec-Control, Resolution switcher for HTC ShiftSome of my UDFs: SDL UDF, SetDefaultDllDirectories, Converting GDI+ Bitmap/Image to SDL Surface
trancexx Posted December 8, 2011 Posted December 8, 2011 We talked about changes to some very basic functions that happened with the release of this beta. Functions like Dec(), Int(), Number() and Hex(). I will go thru some of them here so that you know what's the correct way of using this functions now. The most important thing to understand is default behavior. Let's see how Dec() works. $sHex = "FFFFFFFF" $iHex = Dec($sHex) ConsoleWrite($iHex & @CRLF) ConsoleWrite(VarGetType($iHex) & @CRLF) That code should print: -1 Int32 ...because 0xFFFFFFFF is 32bits wide and in that case the result is 32bit integer (I'm not saying signed because that goes without saying). Another case could be specifying hex string that's wider than 32 bits. What now? Let's see: $sHex = "AAFFFFFFFF" $iHex = Dec($sHex) ConsoleWrite($iHex & @CRLF) ConsoleWrite(VarGetType($iHex) & @CRLF) The result is:734439407615 Int64 ... because there is no way for that number to fit into 32 bit integer without truncation. So, if amount of data fits 32 bits then returned number is 32bit integer. In all other cases it's 64bit integer. Signed, remember. However, you can by specifying second parameter force different interpretations of the input data. $sHex = "FFFFFFFF" $iHex = Dec($sHex, 2) ConsoleWrite($iHex & @CRLF) ConsoleWrite(VarGetType($iHex) & @CRLF) That code prints:4294967295 Int64 Or even:$sHex = "FFFFFFFF" $iHex = Dec($sHex, 3) ConsoleWrite($iHex & @CRLF) ConsoleWrite(VarGetType($iHex) & @CRLF) ...the result of what is:2.12199579047121e-314 Double Almost the same thing can be said for all other mentioned functions. Second optional parameter allows you to have consistent (whatever you choose) output regardless of input. Here's a trick question. What would this print? ConsoleWrite(Hex(23.9) & @CRLF) ♡♡♡ . eMyvnE
jvanegmond Posted December 8, 2011 Posted December 8, 2011 Here's a trick question. What would this print? ConsoleWrite(Hex(23.9) & @CRLF) Not 23 or 24. The examples above show that the "internal" bits do not change, but only the type. So it will print whatever 23.9 is in binary, read out as a 32 bit number, then represented in hex. Correct? github.com/jvanegmond
trancexx Posted December 8, 2011 Posted December 8, 2011 (edited) Not 23 or 24. The examples above show that the "internal" bits do not change, but only the type. So it will print whatever 23.9 is in binary, read out as a 32 bit number, then represented in hex.Correct?Yes, only AutoIt's primitive type isn't float, it's double. Therefore it's 64 bits wide by default.Would you call this scrip breaking or bug fixing? The change is in the logs but nowhere else. Edited December 8, 2011 by trancexx ♡♡♡ . eMyvnE
jvanegmond Posted December 8, 2011 Posted December 8, 2011 (edited) Yes, only AutoIt's primitive type isn't float, it's double. Therefore it's 64 bits wide by default.If the rule to put in 32 or 64 bit type is "fit without truncation" (from your post above), then is it possible that some doubles yield a 32 bit result when truncation is possible? Edited December 8, 2011 by Manadar github.com/jvanegmond
trancexx Posted December 8, 2011 Posted December 8, 2011 If the rule to put in 32 or 64 bit type is "fit without truncation" (from your post above), then is it possible that some doubles yield a 32 bit result when truncation is possible?No that's impossible. ♡♡♡ . eMyvnE
jvanegmond Posted December 8, 2011 Posted December 8, 2011 Back to your other question, I really like this change because it opens some possibilities which are fundamental for every language (or should be). Those who would call it "script breaking" haven't done real programming. github.com/jvanegmond
jchd Posted December 8, 2011 Posted December 8, 2011 I still have a question about this. Since 2's complement isn't symetrical, we do have a problem with one value: Local $File = "numerics.txt" Local $Num = 2147483648 Local $Ber FileDelete($File) FileWriteLine($File, "" & $Num) $Ber = Number(FileReadLine($File)) If $Num <> $Ber Then ConsoleWrite("Data breakage: " & $Num & " changed into " & $Ber & @LF) EndIf Run in 3.3.6.1 and 3.3.7.22 to see the issue. Yet the file is correct in both cases. The point is: reading back stored data, how do we decide if it needs conversion with or without option? Of course we could read the string, explicitely test everywhere Int, Number, ... is used for "2147483648" and convert accordingly. But I find it really uncomfortable if not script- / ball-breaking, irrespective of anyone's programming background. Strings carrying values in this range are not that exceptional and actually occur in real life. This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)
Valik Posted December 8, 2011 Posted December 8, 2011 Hmm. I keep trying to compose this post but every time I start to explain how what AutoIt is doing is wrong I think of another way that it's wrong. I need time to think about this one.
wraithdu Posted December 9, 2011 Posted December 9, 2011 I'm not sure this is wrong. Number() returns a *signed* integer. That value is negative when signed. If you expect to encounter values in that range, you should use Number() with flag 2 to force a 64-bit integer, or Abs().
jaberwacky Posted December 9, 2011 Posted December 9, 2011 (edited) Isn't 2,147,483,648 an overflow? Nevermind, I realized as soon as I posted that the autosized integer should be 64 bit. Really strange: Local Const $Num = "2147483648" Local Const $Ber1 = Number($Num) ConsoleWrite($Ber1 & @CRLF) ; -2147483648 ConsoleWrite(VarGetType($Ber1) & @CRLF) ; INT32 Local Const $Ber2 = Number($Num, 2) ConsoleWrite($Ber2 & @CRLF) ; 2147483648 ConsoleWrite(VarGetType($Ber2) & @CRLF) ; INT64 Forgot to mention that I have an x64 machine. Edit: Wait a second. I must have read it wrong. Edited my example. And ignore everything I ever say from now on forever. Edited December 9, 2011 by LaCastiglione Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum?
jchd Posted December 9, 2011 Posted December 9, 2011 @wraithdu No, the string "2147483648" is definitely positive and needs 64-bit to represent properly. If we have to use the 2 flag in Number, Int and friends when converting every unknown value (e.g. in many UDFs), what's the purpose of autosizing then? This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)
jchd Posted December 9, 2011 Posted December 9, 2011 @Castiou I get a different result: Local Const $Num1 = "2147483648" Local Const $Ber1 = Number($Num1) ConsoleWrite($Ber1 & @CRLF) ; -2147483648 ConsoleWrite(VarGetType($Ber1) & @CRLF) ; INT64 (INT32 on x86) Local Const $Ber2 = Number($Num1, 2) ConsoleWrite($Ber2 & @CRLF) ; 2147483648 ConsoleWrite(VarGetType($Ber2) & @CRLF) ; INT64 This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)
wraithdu Posted December 9, 2011 Posted December 9, 2011 (edited) No, the string "2147483648" is definitely positive and needs 64-bit to represent properly. It may be a positive string (if there is such a thing), but it is only positive as an *unsigned* 32-bit integer, or a 64-bit integer. The largest signed 32-bit integer is 2147483647. Number() converts to a signed 32-bit integer if the data fits, and 2147483648 (0x80000000) definitely fits into a 32-bit space. What's the misunderstanding here? ConsoleWrite(DllStructSetData(DllStructCreate("int"), 1, 2147483648) & @CRLF) ; -2147483648 ConsoleWrite(DllStructSetData(DllStructCreate("uint"), 1, 2147483648) & @CRLF) ; 2147483648 ConsoleWrite(DllStructSetData(DllStructCreate("int64"), 1, 2147483648) & @CRLF) ; 2147483648 Edited December 9, 2011 by wraithdu
jchd Posted December 9, 2011 Posted December 9, 2011 No misunderstanding here. Simply a shift of semantics on your side. That the bits "fit" inside a nibble, a byte, a half-word, a word, a double-word, a long long long long int or any technical container is irrelevant except in DLL* area and technical domains. The issue is the wrong decision to auto-size a 64-bit positive integer value into a 32-bit signed integer.Yes the bits "fit" but the point is that the value doesn't. You don't want to recognize that users need to round-trip data using strings and numeric variants, and files and network and back without having to see their values changed by an unexpected two's complement artifact.How would you feel if your CR $32768 bank balance suddenly gets reported and trusted to be DB $32768, your cards revoked, just because your bank starts using a cheap 16-bit computer and pretends it's correct since "the bits fit"?If AutoIt Devs tomorrow decide to implement new Int8 and Int16 variants to help conserve memory, would you find it convenient to adopt the same dogma? You certainly would expect and prefer an integer expression to return an integer variant wide enough to hold the value verbatim, amplitude and sign, not a truncated bitmap. This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)
Valik Posted December 9, 2011 Posted December 9, 2011 (edited) This is why I need to think about this and experiment. Both ways of doing this are right in some cases. If we just stuff the bits in there that's right because that's the way the bits map out. That method is analogous to a union in C:union Meh { __int64 i64; __int32 i32; };On the other hand, as jchd demonstrated, this method can cause the sign bit to flip incorrectly. The value returned in jchd's example is just flat out wrong.My original thought on fixing numbers in AutoIt was to eliminate 32-bit storage entirely. Store everything in 64-bits and provide cast functions so you can convert your data from 64-bits to 32-bits safely. trancexx decided to do her own thing and there's just this one little quirk left to solve.I think what needs to happen is AutoIt needs to use the presence or lack of a sign flag in a string to determine the sign of the result. Even if the number fits into 32-bits as a negative number, if that sign flag is not in the string then AutoIt needs to treat the number as positive and put it in 64-bits. If the sign flag is present then AutoIt would treat it as a negative number, of course.I think in this situation it is better to do what humans think should happen rather than allow the machine to work "naturally". I understand both methods of handling this situation but I think user expectation is for the sign flag to be honored rather than an implementation detail of computer architecture.Edit: More. I foresaw this issue somewhat, I just didn't think enough about it all to see what jchd has shown and to think up a (potential) solution. I'm the reason for the new flags with Number() and so-forth because I knew there would be problems with the range of negative 32-bit integers that are also positive 64-bit integers. I just didn't think enough about auto-sizing as I thought those flags would cover everything. trancexx did all the implementation. On that note...trancexx, please update the auto-sizing code to look for a sign flag on strings and honor the presence or lack of that flag. This should eliminate the ambiguity between the range of overlapping numbers. Unless I'm missing something... it's been a long day. Edited December 9, 2011 by Valik Extra word
wraithdu Posted December 9, 2011 Posted December 9, 2011 Yes the bits "fit" but the point is that the value doesn't.After reading Valik's post I can see the ambiguity between being mathematically correct and expected output. I agree honoring a numeric string's sign flag is a good solution to the auto-sizing problem.
JohnOne Posted December 9, 2011 Posted December 9, 2011 As someone who does not fully understand, 32bit and 64bit integers, signed or otherwiseand the way computers work, I would be totally agog to see my number flipped in its output. AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans.
trancexx Posted December 9, 2011 Posted December 9, 2011 The number is not flipped. It's like what that spoon boy says "Do not try and bend the spoon ...try to realize the truth". Nevertheless, I will bend the code. What if I see someone saying "Now it breaks my script differently :cry:"? Nothing I guess. I hope that wouldn't happen. ♡♡♡ . eMyvnE
jvanegmond Posted December 9, 2011 Posted December 9, 2011 What is a sign flag in a string? Simply "+" and "-"? So the problem as mentioned above would force into a 64-bit integer because of the lack of a "-" character. Correct? github.com/jvanegmond
Recommended Posts