andybiochem Posted February 17, 2010 Share Posted February 17, 2010 (edited) [EDIT] Function has now been updated. Works with all numbers I have tried so far. If you find an error, please let me know!Hi!I've been meaning to write this UDF for a while, and finally got round to doing it today. A search of the forum returned very little for "significant figures", so I assume this hasn't been done yet.I guess this can be done much more elegantly using regular expressions etc, but my method seems to be fairly robust.Please test out the function and let me know if you encounter any major errors.Note: this whole function would have been sooo much easier if it wasn't for (what I consider to be) an oversight in StringFormat, which I believe is a conversion of stringf in c++? The problem is with padding zeros to the right of a specified width, which apparently:"If width is prefixed with 0, zeros are added until the minimum width is reached (not useful for left-aligned numbers)."...I'd LOVE it if I could pad left-aligned numbers!!!!!!Anyway, here it is in its crappy string manipulated glory (there's some cheeky recursion in there for the recursion-heads!):expandcollapse popup;#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 #include <array.au3> ;----- Numbers to test ----- Global $aTest[11][3] = [["Number To Round", "Significant Figures", "Result"], _ [123456, 14, ""], _ [123456, 2, ""], _ [123456, 1, ""], _ [0.1515, 3, ""], _ [51.525, 3, ""], _ [999.9, 2, ""], _ ["0.000000001245", 3, ""], _ [-12.231231e15, 12, ""], _ [1.3456E-13, 3, ""], _ [-321, 3, ""]] ; ;----- Test Numbers ----- For $i = 1 To 10 $aTest[$i][2] = _SF($aTest[$i][0], $aTest[$i][1]) Next _ArrayDisplay($aTest, "") ; #FUNCTION# ;=============================================================================== ; Name...........: _SF ; Description ...: Rounds the inputted number to the specified Significant Figures ; Syntax.........: _SF($nNumber[, $iSF = 3]) ; Parameters ....: $nNumber - the number to be rounded, can be any AI number style, as a ; number or as a string. If sent as a number, the function is ; limited to AI specifications. ; $iSF - the number of significant figures to round by ; Return values .: Success - Returns the number of SF specified, as a string (intentional) ; Notes .........: Rounding method = "Round Half Away From Zero" ; Author ........: AndyBiochem ; =========================================================================================== Func _SF($nNumber, $iSF = 3) Local $bIsNeg = False, $biDecimal, $aData, $bFoundSF Local $iSFCount, $sTemp ;----- Check Negative ----- If StringLeft($nNumber, 1) = "-" Then $bIsNeg = True If $bIsNeg Then $nNumber = StringReplace($nNumber, "-", "") ;----- Check Form ----- Switch StringInStr($nNumber, "e") Case 0 ;NOT standard form ;- strip any leading zeros (not significant) - $nNumber = StringReplace($nNumber, "0", " ") $nNumber = StringStripWS($nNumber, 1) $nNumber = StringReplace($nNumber, " ", "0") If StringLeft($nNumber, 1) = "." Then $nNumber = "0" & $nNumber ;- get DP if exists & strip out - $biDecimal = StringInStr($nNumber, ".") $nNumber = StringReplace($nNumber, ".", "") ;- Round - $nNumber &= " " ;to prevent array-out error $aData = StringSplit($nNumber, "") $aData[0] = "" $bFoundSF = False $iSFCount = $iSF For $i = 1 To UBound($aData) - 2 If $aData[$i] <> 0 Then $bFoundSF = True If $bFoundSF = False Then ContinueLoop ;- denumerate found SF - $iSFCount -= 1 ;- loop until no SF left - If $iSFCount > 0 Then ContinueLoop ;- round if necessary - If $iSFCount = 0 And $aData[$i + 1] >= 5 Then For $j = $i To 0 Step -1 $aData[$j] += 1 If $aData[$j] = 10 Then $aData[$j] = 0 Else ExitLoop ;number not 10 so exit loop EndIf Next EndIf ;- replace all remaining SF with 0 - If $iSFCount < 0 Then $aData[$i] = "0" Next ;- pick up new data - $sTemp = "" For $i = 0 To UBound($aData) - 2 If $i <> 0 And $i = $biDecimal Then $sTemp &= "." ;add . back in $sTemp &= $aData[$i] Next $sTemp = StringStripWS($sTemp, 1) ;removes [0] if " ;- add any trailing SFs - For $i = 1 To $iSFCount ;$iSFCount will be > 0 if more SFs than digits If $i = 1 Then $sTemp &= "." $sTemp &= "0" Next ;- return - If $bIsNeg Then $sTemp = "-" & $sTemp Return $sTemp Case Else ;IS standard form ;- try to remove standard form (for +ve e) - $nNumber = Number($nNumber) ;- test again - Switch StringInStr($nNumber, "e") Case 0 ;no longer standard form If $bIsNeg Then $nNumber = "-" & $nNumber Return _SF($nNumber, $iSF) Case Else ;still standard form; break out $aData = StringSplit($nNumber, "e") $nNumber = StringReplace($aData[1], ".", "") ;- pad zeros - Switch StringInStr($aData[2], "-") Case 0 ;must be positive For $i = 1 To Number($aData[2]) - (StringLen($aData[1]) - 2) $nNumber &= "0" Next Case Else ;must be negative For $i = 1 To Abs(Number($aData[2])) - 1 $nNumber = "0" & $nNumber Next $nNumber = "0." & $nNumber EndSwitch ;- recurse as non-standard number - If $bIsNeg Then $nNumber = "-" & $nNumber Return _SF($nNumber, $iSF) EndSwitch EndSwitch EndFunc ;==>_SF Edited February 20, 2010 by andybiochem - Table UDF - create simple data tables - Line Graph UDF GDI+ - quickly create simple line graphs with x and y axes (uses GDI+ with double buffer) - Line Graph UDF - quickly create simple line graphs with x and y axes (uses AI native graphic control) - Barcode Generator Code 128 B C - Create the 1/0 code for barcodes. - WebCam as BarCode Reader - use your webcam to read barcodes - Stereograms!!! - make your own stereograms in AutoIT - Ziggurat Gaussian Distribution RNG - generate random numbers based on normal/gaussian distribution - Box-Muller Gaussian Distribution RNG - generate random numbers based on normal/gaussian distribution - Elastic Radio Buttons - faux-gravity effects in AutoIT (from javascript)- Morse Code Generator - Generate morse code by tapping your spacebar! Link to comment Share on other sites More sharing options...
andybiochem Posted February 17, 2010 Author Share Posted February 17, 2010 Please test out the function and let me know if you encounter any major errors...I'm still working on it.ffs found another. update soon... - Table UDF - create simple data tables - Line Graph UDF GDI+ - quickly create simple line graphs with x and y axes (uses GDI+ with double buffer) - Line Graph UDF - quickly create simple line graphs with x and y axes (uses AI native graphic control) - Barcode Generator Code 128 B C - Create the 1/0 code for barcodes. - WebCam as BarCode Reader - use your webcam to read barcodes - Stereograms!!! - make your own stereograms in AutoIT - Ziggurat Gaussian Distribution RNG - generate random numbers based on normal/gaussian distribution - Box-Muller Gaussian Distribution RNG - generate random numbers based on normal/gaussian distribution - Elastic Radio Buttons - faux-gravity effects in AutoIT (from javascript)- Morse Code Generator - Generate morse code by tapping your spacebar! Link to comment Share on other sites More sharing options...
Mat Posted February 17, 2010 Share Posted February 17, 2010 heres my function for rounding in all directions, with an option for significant figures. http://www.autoitscript.com/forum/index.php?showtopic=102686 Yours does look a bit better though AutoIt Project Listing Link to comment Share on other sites More sharing options...
andybiochem Posted February 20, 2010 Author Share Posted February 20, 2010 Function has been update now. Works with all numbers I've thrown at it so far. This was a complete b*&^%"££ to write I thought it'd be easy too. Please let me know if you find any errors! - Table UDF - create simple data tables - Line Graph UDF GDI+ - quickly create simple line graphs with x and y axes (uses GDI+ with double buffer) - Line Graph UDF - quickly create simple line graphs with x and y axes (uses AI native graphic control) - Barcode Generator Code 128 B C - Create the 1/0 code for barcodes. - WebCam as BarCode Reader - use your webcam to read barcodes - Stereograms!!! - make your own stereograms in AutoIT - Ziggurat Gaussian Distribution RNG - generate random numbers based on normal/gaussian distribution - Box-Muller Gaussian Distribution RNG - generate random numbers based on normal/gaussian distribution - Elastic Radio Buttons - faux-gravity effects in AutoIT (from javascript)- Morse Code Generator - Generate morse code by tapping your spacebar! Link to comment Share on other sites More sharing options...
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