czardas Posted September 30, 2011 Share Posted September 30, 2011 (edited) I nearly had working and after changing a few things I got it working as intended, but I can't figure out how I managed to break the Return function. It returns zero when the value is clearly 1111. I must be doing something wrong, but even so, there has to be an explanation as to why this is happening. What did I do? MsgBox(0, "What happened to the return value?", _DecToModeBase(15,2)) Func _DecToModeBase($iDecimal, $iBase, $iRet = 0) If $iDecimal > $iBase Then Local $iPower = 1 While $iDecimal >= $iBase^$iPower $iPower += 1 WEnd $iPower -= 1 Local $iDigit = Int($iDecimal/($iBase^($iPower))) $iRet += $iDigit*(10^$iPower) $iDecimal -= $iDigit*($iBase^$iPower) If $iDecimal >= $iBase Then _DecToModeBase($iDecimal, $iBase, $iRet) Else $iRet += $iDigit MsgBox(0, "Return Value", $iRet) ; value is correct. Return $iRet ; Why is this not working? EndIf EndIf EndFunc Actually the code is wrong, but I think I'm going in the right direction. Edited September 30, 2011 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
MvGulik Posted September 30, 2011 Share Posted September 30, 2011 (edited) Mmm, Still poking around ... But don't you need to do something with the return data from the recursion function-call inside your function ? ;; ... If $iDecimal >= $iBase Then _DecToModeBase($iDecimal, $iBase, $iRet) Else ;; ... --- Try Return _DecToModeBase($iDecimal, $iBase, $iRet) Edited September 30, 2011 by iEvKI3gv9Wrkd41u "Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions.""The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014) "Believing what you know ain't so" ... Knock Knock ... Link to comment Share on other sites More sharing options...
czardas Posted September 30, 2011 Author Share Posted September 30, 2011 (edited) Mmm, Still poking around ... But don't you need to do something with the return data from the recursion function-call inside your function ? ;; ... If $iDecimal >= $iBase Then _DecToModeBase($iDecimal, $iBase, $iRet) Else ;; ... Good thinking! (even though I didn't implement it properly) I also need to go through my logic. There's something not right about it. Edited October 1, 2011 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
KaFu Posted September 30, 2011 Share Posted September 30, 2011 Had a similar problem once but the math went over my head (out of university for 12 years now ... or maybe I just became too lazy ), I've ended up using the excellent " by james3mg. OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2024-Oct-20) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
JohnOne Posted September 30, 2011 Share Posted September 30, 2011 Cheap hack Global $a[3] = [15,2,0] While 1 $val = _DecToModeBase($a[0], $a[1], $a[2]) If @error Then $a[0] = @error $a[1] = @extended $a[2] = $val Else ExitLoop EndIf WEnd MsgBox(0, "What happened to the return value?", $val) Func _DecToModeBase($iDecimal, $iBase, $iRet = 0) If $iDecimal > $iBase Then Local $iPower = 1 While $iDecimal >= $iBase ^ $iPower $iPower += 1 WEnd $iPower -= 1 Local $iDigit = Int($iDecimal / ($iBase ^ ($iPower))) $iRet += $iDigit * (10 ^ $iPower) $iDecimal -= $iDigit * ($iBase ^ $iPower) If $iDecimal >= $iBase Then Return SetError($iDecimal, $iBase, $iRet) Else $iRet += $iDigit MsgBox(0, "Return Value", $iRet) ; value is correct. Return $iRet ; Why is this not working? EndIf EndIf EndFunc ;==>_DecToModeBase Probably doesn't work AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
czardas Posted September 30, 2011 Author Share Posted September 30, 2011 (edited) I think have fixed the logic, but not the recursion error. I think I know the cause. Looking at your code John. Also thanks Kafu, I'll take a look at the link. Some new changes. I think your method will work John, but I want to just call the function once. Still haven't found a solution. It needs some further thought. MsgBox(0, "Result!", _DecToModeBase(6,2)) Func _DecToModeBase($iDecimal, $iBase, $iRet = 0) If $iDecimal >= $iBase Then Local $iPower = 1 While $iDecimal >= $iBase^$iPower $iPower += 1 WEnd $iPower -= 1 Local $iDigit = Int($iDecimal/($iBase^$iPower)) $iRet += $iDigit*(10^$iPower) $iDecimal -= $iDigit*($iBase^$iPower) If $iDecimal >= $iBase Then ;MsgBox(0, "$iRet", $iRet) $iRet = _DecToModeBase($iDecimal, $iBase, $iRet) MsgBox(0, "Recursion error", "How did we get here?") ; Recursion error Else $iRet += $iDecimal MsgBox(0, "Return Value", $iRet) Return $iRet ; Why is this not working? EndIf Else Return $iDecimal EndIf EndFunc Edited September 30, 2011 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
MvGulik Posted October 1, 2011 Share Posted October 1, 2011 (edited) Did you try?Try Return _DecToModeBase($iDecimal, $iBase, $iRet) Edited October 1, 2011 by iEvKI3gv9Wrkd41u "Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions.""The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014) "Believing what you know ain't so" ... Knock Knock ... Link to comment Share on other sites More sharing options...
JohnOne Posted October 1, 2011 Share Posted October 1, 2011 Did you try? That seems to work. AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
MvGulik Posted October 1, 2011 Share Posted October 1, 2011 (edited) Seems to work ok to me. (czardas last version with suggested change.) Some code-result tester function.Func test_DecToModeBase() Local $iMaxBaseRange = 4 Local $iMaxDecimalMultiple = 4 Local $iTestFunctions = 2 Local $aResults[$iTestFunctions] $iMaxDecimalMultiple -= 1 ;; run up to first instance of N multiple's. For $iBase = 2 To $iMaxBaseRange For $iDecimal = 0 To Int($iBase ^ $iMaxDecimalMultiple) ;~ $aResults[0] = _DecToModeBase12($iDecimal, $iBase) $aResults[1] = _DecToModeBase($iDecimal, $iBase) ConsoleWrite($iDecimal & ', ' & $iBase & ': ' & $aResults[0] & ', ' & $aResults[1] & @CRLF) Next Next EndFunc +'For $iDecimal ...' fix. Edited October 1, 2011 by iEvKI3gv9Wrkd41u "Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions.""The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014) "Believing what you know ain't so" ... Knock Knock ... Link to comment Share on other sites More sharing options...
czardas Posted October 1, 2011 Author Share Posted October 1, 2011 (edited) Did you try? Yeah, it didn't help. I must have done something wrong. Please show me where you put the new line, because I'm still getting the wrong return value. Here's a solution using a global variable, but that's not entirely satisfactory. Global $iResult _DecToModeBase(15,3) MsgBox(0, "Result!", $iResult) Func _DecToModeBase($iDecimal, $iBase, $iRet = 0) Local $iReturnValue If $iDecimal >= $iBase Then Local $iPower = 1 While $iDecimal >= $iBase^$iPower $iPower += 1 WEnd $iPower -= 1 Local $iDigit = Int($iDecimal/($iBase^$iPower)) $iRet += $iDigit*(10^$iPower) $iDecimal -= $iDigit*($iBase^$iPower) If $iDecimal >= $iBase Then _DecToModeBase($iDecimal, $iBase, $iRet) Else $iResult = $iRet + $iDecimal EndIf Else $iResult = $iDecimal EndIf EndFunc I guess I need to get used to using recursion. Edited October 1, 2011 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
JohnOne Posted October 1, 2011 Share Posted October 1, 2011 MsgBox(0, "Result!", _DecToModeBase(6,2)) Func _DecToModeBase($iDecimal, $iBase, $iRet = 0) If $iDecimal >= $iBase Then Local $iPower = 1 While $iDecimal >= $iBase^$iPower $iPower += 1 WEnd $iPower -= 1 Local $iDigit = Int($iDecimal/($iBase^$iPower)) $iRet += $iDigit*(10^$iPower) $iDecimal -= $iDigit*($iBase^$iPower) If $iDecimal >= $iBase Then ;MsgBox(0, "$iRet", $iRet) Return _DecToModeBase($iDecimal, $iBase, $iRet) MsgBox(0, "Recursion error", "How did we get here?") ; Recursion error Else $iRet += $iDecimal MsgBox(0, "Return Value", $iRet) Return $iRet ; Why is this not working? EndIf Else Return $iDecimal EndIf EndFunc AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
MvGulik Posted October 1, 2011 Share Posted October 1, 2011 (edited) You do need to change the right code line of course. ;-)Here, works the way I think you intended. Hehe, JohnOne's code will do.---czardas. Look at the path of your code IF you don't put a Return in the 'if ... _DecToModeBase ... else' block.Your function will return nothing, as it fall trough to the EndFunc part. (Return 0) Edited October 1, 2011 by iEvKI3gv9Wrkd41u "Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions.""The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014) "Believing what you know ain't so" ... Knock Knock ... Link to comment Share on other sites More sharing options...
czardas Posted October 1, 2011 Author Share Posted October 1, 2011 (edited) Lol. Thanks guys. It's funny how you get so close and still all you can see is the fog. Much appreciated. iEvKI3gv9Wrkd41uGot ya! Of course it only works for number bases from binary to decimal base 9. Error checks are still missing and the code needs to be tidied up a little. I'll probably add it to my Snippet Dump thread with one or two other functions in due course. Edited October 1, 2011 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
MvGulik Posted October 1, 2011 Share Posted October 1, 2011 (edited) Could not stop playing around with your code ... ;; issue with bigger numbers: float only allouwing 15 significant digits to be stored. -> need to use string to bypass this. ... Func _DecToModeBase41($iDecimal, $iBase) ;; pre-checkup part. If $iBase < 2 Then Return SetError(1, 0, 0) ;; invalid base value. If $iBase > 10 Then Return SetError(2, 0, 0) ;; unsupported base value. If $iBase = 10 Then Return $iDecimal ;; nothing to do. If $iDecimal < $iBase Then Return $iDecimal ;; nothing to do. If Floor(Log($iDecimal) / Log($iBase)) > 15 Then Return SetError(3, 0, 0) ;; unsupported combination. float output limitation. Local $iRet = 0 _DecToModeBase42($iDecimal, $iBase, $iRet) Return $iRet EndFunc Func _DecToModeBase42($iDecimal, ByRef Const $iBase, ByRef $iRet) ;; recurse part. Local $iPower = Floor(Log($iDecimal) / Log($iBase)) Local $iDigit = Int($iDecimal / ($iBase ^ $iPower)) $iRet += $iDigit * (10 ^ $iPower) $iDecimal -= $iDigit * ($iBase ^ $iPower) If $iDecimal < $iBase Then $iRet += $iDecimal Else _DecToModeBase42($iDecimal, $iBase, $iRet) EndIf EndFunc+minor fix.... Edited October 1, 2011 by iEvKI3gv9Wrkd41u czardas 1 "Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions.""The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014) "Believing what you know ain't so" ... Knock Knock ... Link to comment Share on other sites More sharing options...
czardas Posted October 1, 2011 Author Share Posted October 1, 2011 (edited) I feel honoured. Yes the limitations are 15 digits. I was going to look into adding some error checks today (it seems you did that for me ). The smaller the base, the smaller the max decimal input value: due to the limitations of the method. It was really nothing more than a recursion coding exercise for myself, although I'll add a function to reverse the proceedure and one to combine them. Something like => _BaseToModeBase($iVal, $iBase1, $iBase2) I like the way you sneaked the logarithmic function in there. Good thinking. Edited October 1, 2011 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
czardas Posted October 1, 2011 Author Share Posted October 1, 2011 (edited) Added one or two additional checks and arguments to support negative decimal input values. Any further suggestions?Func _DecToModeBase41($iDecimal, $iBase) If IsInt($iBase) = 0 Or $iBase < 2 Or $iBase > 10 Then Return SetError(1, 0, 0) ; Invalid base value If IsInt($iDecimal) = 0 Then Return SetError(2, 0, 0) ; Invalid decimal value Local $iSign = 1, $iRet = 0 If $iDecimal < 0 Then $iSign = -1 $iDecimal *= $iSign ; Force positive decimal value If $iDecimal < $iBase Or $iBase = 10 Then Return $iDecimal * $iSign ; Nothing to do If Floor(Log($iDecimal) / Log($iBase)) > 15 Then Return SetError(3, 0, 0) ; Float output limitation _DecToModeBase42($iDecimal, $iBase, $iRet) Return $iRet * $iSign EndFunc Func _DecToModeBase42($iDecimal, $iBase, ByRef $iRet) Local $iPower = Floor(Log($iDecimal) / Log($iBase)) ; Courtesy of iEvKI3gv9Wrkd41u Local $iDigit = Int($iDecimal / ($iBase ^ $iPower)) $iRet += $iDigit * (10 ^ $iPower) $iDecimal -= $iDigit * ($iBase ^ $iPower) If $iDecimal < $iBase Then $iRet += $iDecimal Else _DecToModeBase42($iDecimal, $iBase, $iRet) EndIf EndFuncAnd here's a method to reverse the proceedure, No error checks or neg value support ATM.#include <String.au3> Func _ModeBaseToDec($iModeVal, $iBase) $iModeVal = _StringReverse($iModeVal) Local $iRet = 0, $aBaseDigit = StringSplit($iModeVal, "", 2) For $i = 0 To UBound($aBaseDigit) -1 $iRet += $aBaseDigit[$i]*($iBase^$i) Next Return $iRet EndFunc Final EditThe finsihed product is Thanks for all the help folks. Edited October 2, 2011 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
MvGulik Posted October 2, 2011 Share Posted October 2, 2011 (edited) The finsihed product is Nice. PS: ... ; Courtesy of iEvKI3gv9Wrkd41u ... by way of Log() Help example. Edited October 2, 2011 by iEvKI3gv9Wrkd41u "Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions.""The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014) "Believing what you know ain't so" ... Knock Knock ... 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