Jump to content

Round Function


Recommended Posts

ProgAndy is refering there to the ULP (google "unit in the last place") in the vincinity of the number you represent.

I was preparing a post with low-level explanation about what happens with FP, but finally decided it was a "bit" technical for the General help audience.

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)

Link to comment
Share on other sites

I find it hard to believe what I'm reading. I consider this to be very serious indeed. We can't just go around saying oh it's a problem with the FP and binary. Consider the life and death case scenarios that could occur by wrong decisions based on misinterpretation. Incorrect space flight calculations, financial markets and accounting anomolies. I think something like this can have a huge impact if not ammended in some way.

Edited by czardas
Link to comment
Share on other sites

I find it hard to believe what I'm reading. I consider this to be very serious indeed. We can't just go around saying oh it's a problem with the FP and binary. Consider the life and death case scenarios that could occur by wrong decisions based on misinterpretation. Incorrect space flight calculations, financial markets and accounting anomolies. I think something like this can have a huge impact if not ammended in some way.

This is a floating point issue. If you need better precision, use another data format. http://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

This is a floating point issue. If you need better precision, use another data format. http://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic

Now that I'm aware of this I will be cautious when using Round and probably replace the function with another. I understand what is happening. Thanks!

Edited by czardas
Link to comment
Share on other sites

What I used to do, back in the old days of Pre-IBM style PCs, was to figure out how many places I needed to round off to to the right of the decimal point, then multiply the number by 10^n, add 0.5 to that number, and then divide again by 10* the decimal places to get the number rounded off. For example taking the original figure of the OP

4.515 rounded off to 2 places is done like this

4.515 * 100 = 451.5

Int(451.5 + 0.5) = 452

452/100 = 4.52

Or in AutoIt it would look something like this, which of course could be shortened into one line or made into a function to do the same thing as Round does, but accurately.

$Num = 4.515 * 100
$Num += .5
$num = Int($num) / 100
ConsoleWrite($num & @LF)
Edited by BrewManNH

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

Link to comment
Share on other sites

I recently set 600 ms to be a default value for a particular purpose, because of the high number of prime factors. The types of division I intend to employ will mainly produce whole numbers, and therefore avoid any FP anomolies. I also consider that rounding should be avoided until the last return value. Then we should get fairly high presision (14 or 15 digits), after which I'll probably employ string functions to do the rounding.

Edited by czardas
Link to comment
Share on other sites

4.515 rounded off to 2 places is done like this

4.515 * 100 = 451.5

Int(451.5 + 0.5) = 452

452/100 = 4.52

Or in AutoIt it would look something like this, which of course could be shortened into one line or made into a function to do the same thing as Round does, but accurately.

$Num = 4.515 * 100
$Num += .5
$num = Int($num) / 100
ConsoleWrite($num & @LF)

It works on this example, but you need to add or subtract 0.5 depending on the sign of $num.

Also, it produces mindbogling intermediate results. I'm unsure about the validity in all cases:

$Num = 4.515 * 100
If $num < 451.5 Then ConsoleWrite($num & ' < 451.5' & @LF)
$Num += .5
If $num < 452 Then ConsoleWrite($num & ' < 452' & @LF)
$num = Int($num) / 100
ConsoleWrite($num & @LF)

Here we rely on Int() applying its own correction, as explained in the help file, where it's clearly stated that there are rare cases where it won't work the way we would expecting.

Edited by jchd

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)

Link to comment
Share on other sites

I once (many, many years ago) had a school subject named "Numerical analysis". It allowed to calculate the accuracy of an algorithm. For me this linked mathematics to real life ;)

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

The intermediate results probably shouldn't cause too many issues because the end result is what is important, after all the conversions are done that is. I guess you'd have to run it through a bunch of tests to see just how accurate it is compared to Round() before deciding which is right for the job. Also, the negative check is fairly simple, something like

If $num < 0 Then
    $num -= 0.5
Else
    $num += 0.5
Endif
Edited by BrewManNH

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

Link to comment
Share on other sites

I took the example from post and applied my _Round function to it to check it's accuracy. Here's the new script with the new Round function, this will tell us if this method can work better than the original Round() function.

Local $i_RoundDown = 0, $i_RoundUp = 0
For $h = 0 To 9
    ConsoleWrite(@LF & "============== Check numbers that _Rounded down to " & $h & " ========================" & @LF)
    For $i = 0 To 99
        For $j = 0 To 9
            $a = StringFormat("%2.2f", _Round(Number($i & "." & $j & $h & "5"), 2))
            If StringRight($a, 1) = $h Then
                ConsoleWrite("#" & $a & "#" & @TAB)
                $i_RoundDown += 1
            Else
                ConsoleWrite(" " & $a & " " & @TAB)
                $i_RoundUp += 1
            EndIf
        Next
        ConsoleWrite(@LF)
    Next
Next
ConsoleWrite(" _Round down = " & $i_RoundDown & " out of " & $i_RoundDown + $i_RoundUp & " (" & $i_RoundDown * 100 / ($i_RoundDown + $i_RoundUp) & "%)" & @LF)
Func _Round($nNumber, $iPlaces = 2)
    $nDecimal = 10 ^ $iPlaces
    $nNumber = $nNumber * $nDecimal
    If $nNumber < 0 Then
        $nNumber -= .5
    Else
        $nNumber += .5
    EndIf
    $nNumber = Int($nNumber) / $nDecimal
    Return $nNumber
EndFunc   ;==>_Round

EDIT: I ran this test on numbers with decimal places out to about 16 places. It's pretty accurate out to 12 decimal places, then you start get anomalies where the last number gets rounded up 2 rather than getting rounded down 1, which is further evidence that floating point math is not very good for accuracy. ;) But, if you need a rounding function that will work out to 12 places, this one seems to work ok.

Edited by BrewManNH

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

Link to comment
Share on other sites

Attempting to round whilst accounting for floating point precision is always doomed to failure.

Any rounding workaround will always get one of these numbers wrong

4.515

4.514999999999999

"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

Link to comment
Share on other sites

Testing the second number with the _Round() function I posted above, it comes out right, but the script sees it as 4.515 when I sent it to the function. Removing one 9 from the end, making the mantissa 14 digits long, it displays correctly in a consolewrite. But, if you round 4.514999999999999 you will get 4.515 if using anything larger than 2 in the function which would be the correct answer.

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

Link to comment
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
 Share

  • Recently Browsing   0 members

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