gil900

Strange behavior or a bug in Autoit - Neither!

12 posts in this topic

#1 ·  Posted (edited)

Hi,

I think that this is a bug:

$iMax = 14/5
$iMax = $iMax-Int($iMax)
$iMax *= 5

ConsoleWrite("$iMax is: "&$iMax & @CRLF&@CRLF) ; Print $iMax as 4


; Bug 1: this will end at 3 while $iMax is 4!
ConsoleWrite("Starting loop from 1 to "&$iMax&":" & @CRLF)
For $a = 1 To $iMax
    ConsoleWrite($a & @CRLF)
Next
ConsoleWrite("Done!" & @CRLF & @CRLF)



; Bug 2: the array will be with 3 rows and not 4.
ConsoleWrite("Creating array with "&$iMax&" rows:" & @CRLF)
Local $aArray[$iMax+1]
ConsoleWrite("array size: "& UBound($aArray)-1 & @CRLF)

 

 

Output:

Quote

$iMax is: 4

Starting loop from 1 to 4:
1
2
3
Done!

Creating array with 4 rows:
array size: 3

Runned on Autoit 3.3.14.2

 

If that's not a bug, I really, really want to know what is the explanation for this very unexpected behavior.

 

 

Edited by Melba23
Amended title

Share this post


Link to post
Share on other sites



When doing floating point math, the numbers aren't exactly what they appear to be.

Try this modification:

$iMax = Int($iMax*5)

Now you'll get what you want.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

The problem is that $iMax is "double".

$iMax = 14 / 5
$iMax = $iMax - Int($iMax)
$iMax = $iMax * 5

ConsoleWrite(VarGetType($iMax) & @CRLF)

$iMax = Int($iMax)

ConsoleWrite("$iMax is: " & $iMax & @CRLF & @CRLF) ; Print $iMax as 4


; Bug 1: this will end at 3 while $iMax is 4!
ConsoleWrite("Starting loop from 1 to " & $iMax & ":" & @CRLF)
For $a = 1 To $iMax
    ConsoleWrite($a & @CRLF)
Next
ConsoleWrite("Done" & @CRLF & @CRLF)



; Bug 2: the array will be with 3 rows and not 4.
ConsoleWrite("Creating array with " & $iMax & " rows:" & @CRLF)
Local $aArray[$iMax + 1]
ConsoleWrite("array size: " & UBound($aArray) - 1 & @CRLF)

 

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

15 minutes ago, BrewManNH said:

When doing floating point math, the numbers aren't exactly what they appear to be.

Try this modification:

$iMax = Int($iMax*5)

Now you'll get what you want.

 
 

Yes,
I noticed that the "bug" only happens if I get $iMax with this kind of
math. I just started to learn c++ and this scenario has taught me something new.

but I didn't expected to learn it from Autoit..

 

From what I understand about how Autoit should work on paper by  design, It should work as normal person can expect (4 is 4 and not 3). and not work like tricky language like C.

according to this view, this is bug. - I mean, If Autoit was C so ok, this is not bug. but it is Autoit. so this is bug...

 

 

Edited by gil900

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

What I cannot understand is why these are different results:

$iMax = 14 / 5
$iMax = $iMax - Int($iMax)
$iMax = $iMax * 5.0 ;result should be 4.0

ConsoleWrite("$iMax is: " & $iMax & @CRLF & @CRLF) ; Print $iMax as 4

; Bug 1: this will end at 3 while $iMax is 4!
ConsoleWrite("Starting loop from 1 to " & $iMax & ":" & @CRLF)
ConsoleWrite(VarGetType($iMax) & @CRLF)
For $a = 1 To $iMax
    ConsoleWrite($a & @CRLF)
Next
ConsoleWrite(@CRLF)

ConsoleWrite(VarGetType(4.0) & @CRLF)
For $a = 1 To 4.0
    ConsoleWrite($a & @CRLF)
Next
ConsoleWrite("Done" & @CRLF & @CRLF)

Shouldn't be the same result? :think:

 

Edit:

Seems to be that $iMax <> 4.0 internally.

$iMax = 14 / 5
$iMax = $iMax - Int($iMax)
$iMax = $iMax * 5.0

ConsoleWrite(Hex($iMax) & @CRLF)
ConsoleWrite(Hex(4.0) & @CRLF)

Result is:

400FFFFFFFFFFFFE
4010000000000000

 

That could be the reason for the different result.

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites
12 minutes ago, UEZ said:

What I cannot understand is why these are different results:

$iMax = 14 / 5
$iMax = $iMax - Int($iMax)
$iMax = $iMax * 5.0 ;result should be 4.0

ConsoleWrite("$iMax is: " & $iMax & @CRLF & @CRLF) ; Print $iMax as 4

; Bug 1: this will end at 3 while $iMax is 4!
ConsoleWrite("Starting loop from 1 to " & $iMax & ":" & @CRLF)
ConsoleWrite(VarGetType($iMax) & @CRLF)
For $a = 1 To $iMax
    ConsoleWrite($a & @CRLF)
Next
ConsoleWrite(@CRLF)

ConsoleWrite(VarGetType(4.0) & @CRLF)
For $a = 1 To 4.0
    ConsoleWrite($a & @CRLF)
Next
ConsoleWrite("Done" & @CRLF & @CRLF)

Shouldn't be the same result? :think:

According to this, that fact that it is Double may not the be cause for this behavior.

 
Maybe there is really bug here (I just don't know where exactly)

 

Share this post


Link to post
Share on other sites

the 15th decimal place jacks you every time :)  If I understood anything at all about floating points I could tell you why changing the 14 to a 15 breaks it.

$iMax = 14/5
$iMax = $iMax - Int($iMax)
$iMax = round($iMax * 5 , 14)

ConsoleWrite("$iMax is: "&$iMax & @CRLF&@CRLF) ; Print $iMax as 4


; Bug 1: this will end at 3 while $iMax is 4!
ConsoleWrite("Starting loop from 1 to "&$iMax&":" & @CRLF)
For $a = 1 To $iMax
    ConsoleWrite($a & @CRLF)
Next
ConsoleWrite("Done!" & @CRLF & @CRLF)



; Bug 2: the array will be with 3 rows and not 4.
ConsoleWrite("Creating array with "&$iMax&" rows:" & @CRLF)
Local $aArray[$iMax+1]
ConsoleWrite("array size: "& UBound($aArray)-1 & @CRLF)

 


,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post


Link to post
Share on other sites

just because float has only 14 sure digit precision

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

This might help you understand

$dMax = 14/5
ConsoleWrite("$dMax is: "&StringFormat("%0.20f",$dMax) & @CRLF&@CRLF) ;
$dMax = $dMax-Int($dMax)
ConsoleWrite("$dMax is: "&StringFormat("%0.20f",$dMax) & @CRLF&@CRLF) ;

$dMax *= 5

; Bug 1: this will end at 3 while $iMax is 4!
ConsoleWrite("Starting loop from 1 to "&StringFormat("%0.20f",$dMax)&":" & @CRLF)
For $a = 1 To $dMax
    ConsoleWrite($a & @CRLF)
Next
ConsoleWrite("Done!" & @CRLF & @CRLF)

$iMax = Round($dMax)
ConsoleWrite("Starting loop from 1 to "&StringFormat("%0.20f",$iMax)&":" & @CRLF)
For $a = 1 To $iMax
    ConsoleWrite($a & @CRLF)
Next
ConsoleWrite("Done!" & @CRLF & @CRLF)


; Bug 2: the array will be with 3 rows and not 4.
ConsoleWrite("Creating array with "&$iMax&" rows:" & @CRLF)
Local $aArray[$iMax+1]
ConsoleWrite("array size: "& UBound($aArray)-1 & @CRLF)

 

Edited by Bowmore

"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to build bigger and better idiots. So far, the universe is winning."- Rick Cook

Share this post


Link to post
Share on other sites
1 hour ago, Bowmore said:

This might help you understand

$dMax = 14/5
ConsoleWrite("$dMax is: "&StringFormat("%0.20f",$dMax) & @CRLF&@CRLF) ;
$dMax = $dMax-Int($dMax)
ConsoleWrite("$dMax is: "&StringFormat("%0.20f",$dMax) & @CRLF&@CRLF) ;

$dMax *= 5

; Bug 1: this will end at 3 while $iMax is 4!
ConsoleWrite("Starting loop from 1 to "&StringFormat("%0.20f",$dMax)&":" & @CRLF)
For $a = 1 To $dMax
    ConsoleWrite($a & @CRLF)
Next
ConsoleWrite("Done!" & @CRLF & @CRLF)

$iMax = Round($dMax)
ConsoleWrite("Starting loop from 1 to "&StringFormat("%0.20f",$iMax)&":" & @CRLF)
For $a = 1 To $iMax
    ConsoleWrite($a & @CRLF)
Next
ConsoleWrite("Done!" & @CRLF & @CRLF)


; Bug 2: the array will be with 3 rows and not 4.
ConsoleWrite("Creating array with "&$iMax&" rows:" & @CRLF)
Local $aArray[$iMax+1]
ConsoleWrite("array size: "& UBound($aArray)-1 & @CRLF)

 

Thanks.

Now it make make sense.

But why 14/5 is 2.79999999999999980000 ?

And why it didn't choose to display this number in the console?

 

I tested it now on C++ and got the same behavor

Screenshot_1.png.cfc4f1f227d54ba0f2680df

#include "stdafx.h"
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
    float x = 14.0 / 5.0;
    x -= int(x);
    x *= 5;

    cout << "Starting loop from 1 to " << x << endl;
    for (int i = 1; i <= x; i++)
    {
        cout << i << endl;
    }
    while (1) { Sleep(100); }
    return 1;
}

 

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

http://www.plantation-productions.com/Webster/www.artofasm.com/Linux/HTML/RealArithmetic.html

Depending of setting the Rounding-control Register different results are to be expected. 

From time to time I write programs in assembler, and a long time ago i noticed different results comparing floating-point math calculations to AutoIt! The cause is that AutoIt uses Windows-API-Functions where the registersettings are established since decades....

Setting those Control-Registers "in the right way" (the usually used way from the sight of a Programmer) gives me "right" (equal to AutoIt-Calculations) results...

People have to notice,  that today there is no need to have  "right" results when calculating floating-point math! The most important thing is, that the results are EQUAL when calculating those maths on different machines!

With this informations in mind there is a simple trick to solve those problems. Trust the API, not your brain... so there exist no "bugs" when the result is the same on other machines too...

 

This is the way i set control-register to get equal results to AutoIt when calculating Floating-point math: (like C/C++/HLL does since decades ;) )

finit

    fstcw ctrlWord
    and ctrlWord, 000000111111b                           ;bit 8+9 ;53 Bit genauigkeit, um Kompatibilität zu AutoIt zu erreichen
    or ctrlWord,  001000000000b                           ;bit 10+11 abrunden wg INT
    fldcw ctrlWord

 

 

 

But why 14/5 is 2.79999999999999980000 ?

IEEE 754 Converter, have a look at the line "after casting to double precision"

http://www.h-schmidt.net/FloatConverter/IEEE754.html

Edited by AndyG

Share this post


Link to post
Share on other sites

Use Fraction.au3 and never have to worry about this kind of problem ever again. 2c

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now