jchd Posted April 23, 2012 Posted April 23, 2012 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 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)
czardas Posted April 23, 2012 Posted April 23, 2012 (edited) 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 April 23, 2012 by czardas operator64 ArrayWorkshop
ProgAndy Posted April 23, 2012 Posted April 23, 2012 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
czardas Posted April 23, 2012 Posted April 23, 2012 (edited) This is a floating point issue. If you need better precision, use another data format. http://en.wikipedia.org/wiki/Arbitrary-precision_arithmeticNow 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 April 23, 2012 by czardas operator64 ArrayWorkshop
BrewManNH Posted April 23, 2012 Posted April 23, 2012 (edited) 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 April 23, 2012 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 GudeHow 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
czardas Posted April 23, 2012 Posted April 23, 2012 (edited) 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 April 23, 2012 by czardas operator64 ArrayWorkshop
jchd Posted April 23, 2012 Posted April 23, 2012 (edited) 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 April 23, 2012 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 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)
water Posted April 23, 2012 Posted April 23, 2012 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 2024-07-28 - Version 1.6.3.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 (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
BrewManNH Posted April 23, 2012 Posted April 23, 2012 (edited) 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 April 23, 2012 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 GudeHow 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
BrewManNH Posted April 23, 2012 Posted April 23, 2012 (edited) 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 ;==>_RoundEDIT: 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 April 23, 2012 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 GudeHow 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
Bowmore Posted April 23, 2012 Posted April 23, 2012 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
BrewManNH Posted April 23, 2012 Posted April 23, 2012 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 GudeHow 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
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now