Jump to content

Recommended Posts

Posted

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.
Posted

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

Posted (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 by trancexx

♡♡♡

.

eMyvnE

Posted (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 by Manadar
Posted

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

Posted

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 here
RegExp tutorial: enough to get started
PCRE 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)

Posted

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.

Posted

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().

Posted (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 by LaCastiglione
Posted

@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 here
RegExp tutorial: enough to get started
PCRE 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)

Posted

@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 here
RegExp tutorial: enough to get started
PCRE 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)

Posted (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 by wraithdu
Posted

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 here
RegExp tutorial: enough to get started
PCRE 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)

Posted (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 by Valik
Extra word
Posted

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.
Posted

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

Guest
This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...