Jump to content
Sign in to follow this  
czardas

Return value lost in transit

Recommended Posts

czardas

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? :graduated:

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 by czardas

Share this post


Link to post
Share on other sites
MvGulik

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 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 ...
 

Share this post


Link to post
Share on other sites
czardas

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) :graduated:

I also need to go through my logic. There's something not right about it.

Edited by czardas

Share this post


Link to post
Share on other sites
KaFu

Had a similar problem once but the math went over my head (out of university for 12 years now :graduated:... or maybe I just became too lazy ;)), I've ended up using the excellent " by james3mg.

Share this post


Link to post
Share on other sites
JohnOne

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.

Share this post


Link to post
Share on other sites
czardas

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 by czardas

Share this post


Link to post
Share on other sites
MvGulik

Did you try?

Try

Return _DecToModeBase($iDecimal, $iBase, $iRet)
Edited 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 ...
 

Share this post


Link to post
Share on other sites
MvGulik

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 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 ...
 

Share this post


Link to post
Share on other sites
czardas

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 by czardas

Share this post


Link to post
Share on other sites
JohnOne

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.

Share this post


Link to post
Share on other sites
MvGulik

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 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 ...
 

Share this post


Link to post
Share on other sites
czardas

Lol. Thanks guys. It's funny how you get so close and still all you can see is the fog. Much appreciated. :graduated:

iEvKI3gv9Wrkd41u

Got 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 by czardas

Share this post


Link to post
Share on other sites
MvGulik

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.

... Posted Image

Edited by iEvKI3gv9Wrkd41u
  • Like 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 ...
 

Share this post


Link to post
Share on other sites
czardas

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. :graduated:

Edited by czardas

Share this post


Link to post
Share on other sites
czardas

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
EndFunc

And 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 Edit

The finsihed product is

Thanks for all the help folks. :graduated:

Edited by czardas

Share this post


Link to post
Share on other sites
MvGulik

The finsihed product is

Nice.

PS:

... ; Courtesy of iEvKI3gv9Wrkd41u ... by way of Log() Help example.
:graduated: Edited 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 ...
 

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
Sign in to follow this  

×