## Reverse a number

General FreeBASIC programming questions.
lrcvs
Posts: 575
Joined: Mar 06, 2008 19:27
Location: Spain

### Reverse a number

Hi:

Surfing the net, I have seen this method to do the reverse of a number.
I did not know this method is very fast, simple and small.

Code: Select all

`Dim as ulongint n,temp,reverseclsn = reverse = temp  = 0Input "Number = ";n temp = n '::::::::::::::::::::::::::::::::::::::::::::::::'Reverse a number !!!    While temp <> 0       reverse = (reverse * 10) + (temp Mod 10)      temp = Int(temp/10)       Wend'::::::::::::::::::::::::::::::::::::::::::::::::    Print    Print "Reverse = ";reverse    Print    If n = reverse  Then      Print "Yes, is a palindrome number"    Else      Print "Not, is a palindrome number"    End If     SleepEnd`

Regards
Tourist Trap
Posts: 2817
Joined: Jun 02, 2015 16:24

### Re: Reverse a number

lrcvs wrote:I did not know this method is very fast, simple and small.

It seems to be about 6 times faster than a very basic string reversion. But more comparison can be done, I've been using this code :

Code: Select all

`''Prog to compare 2 number-reversion methods'Function ReverseIRCVS( ByVal Num_ As ULongInt ) As ULongInt   Dim As ULongInt temp_ = Num_   Dim as ULongInt reverse_ = 0      '::::::::::::::::::::::::::::::::::::::::::::::::   'Reverse a number !!!        While temp_ <> 0          reverse_ = (reverse_ * 10) + (temp_ Mod 10)          temp_ = Int(temp_/10)          Wend    '::::::::::::::::::::::::::::::::::::::::::::::::       Return reverse_End Function 'ULONGINT := ReverseIRCVS(ULONGINT)Function ReverseOtherMethod( ByVal Num_ As ULongInt ) As ULongInt   Dim as ULongInt reverse_ = 0   Dim As String numString_ = Str(Num_)   Dim As String tempString = ""      For _i As UInteger = Len(numString_) To 1  Step -1        numString_ = Left(numString_, _i)       tempString &= Right(numString_, 1)   Next _i         reverse_ = CULngInt(tempString)      Return reverse_End Function 'ULONGINT := ReverseOtherMethod(ULONGINT)''_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_ClsRandomize TimerDim As String _inkey = ""Dim As Double t1_ = 0Dim As Double t2_ = 0Dim As ULongInt number_ , reverse_Do    number_ = 1e+9 + CULngInt (Rnd * 109999999900000000)        Locate 2, 4 : ? "  +--------+"    Locate 3, 4 : ? " / NUMBER /" & Space(10) & number_    Locate 4, 4 : ? "+--------+ "        Locate 6, 4 : ? "  +---------+"    Locate 7, 4 : ? " / REVERSE /"    Locate 8, 4 : ? "+---------+ "       t1_ = Timer    reverse_ = ReverseIRCVS( number_ )    t1_ = Timer - t1_     Locate 7, 4 : ? Tab(19); "IRCVS "; reverse_    Locate 8, 4 : ? Tab(24); t1_  * 1e+6       t2_ = Timer    reverse_ = ReverseOtherMethod( number_ )    t2_ = Timer - t2_     Locate 10, 4 : ? Tab(19); "Other ";  reverse_     Locate 11, 4 : ? Tab(24); t2_ * 1e+6       ? : ? : ? "    Time ratio : "; t2_ / t1_        ? : ? : ? "    [SPACE] to pause, then [ESC]x2 to quit"    _inkey = Inkey    Sleep 2000     Sleep -(InKey=Chr(32))*15000    Loop Until _inkey = Chr(27)? "END"Sleep : End''_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_     `
lrcvs
Posts: 575
Joined: Mar 06, 2008 19:27
Location: Spain

### Re: Reverse a number

Ok, Tourist Trap:

1) This method is not mine. I have seen on the net and adapted to Basic.

2) Your comparisons show that there is a ratio of 6:1, compared with a loop between "For ..." and this method.

Thank you very much for your comparison program. !!!

Regards
Tourist Trap
Posts: 2817
Joined: Jun 02, 2015 16:24

### Re: Reverse a number

lrcvs wrote:2) Your comparisons show that there is a ratio of 6:1, compared with a loop between "For ..." and this method.

You may find something faster, I don't know. However there is a little problem. I dont know why, the program will generally work but sometimes it will give a result like this:
number : 794 815 122 644 259 637

reverse : (7) 369 524 462 215 184 97 1

Number in red is missing, and number in black doesn't seem to come from initial data. But the fact that it is exactly the same 'bug' with your fast method and the string method, seems to indicate a problem with ULongInt?
Last edited by Tourist Trap on Jul 12, 2015 23:20, edited 1 time in total.
lrcvs
Posts: 575
Joined: Mar 06, 2008 19:27
Location: Spain

### Re: Reverse a number

Ok!

Use "CLS"

Code: Select all

`    '    'Prog to compare 2 number-reversion methods    '    Function ReverseIRCVS( ByVal Num_ As ULongInt ) As ULongInt        Dim As ULongInt temp_ = Num_        Dim as ULongInt reverse_ = 0               '::::::::::::::::::::::::::::::::::::::::::::::::       'Reverse a number !!!            While temp_ <> 0              reverse_ = (reverse_ * 10) + (temp_ Mod 10)              temp_ = Int(temp_/10)              Wend        '::::::::::::::::::::::::::::::::::::::::::::::::              Return reverse_    End Function 'ULONGINT := ReverseIRCVS(ULONGINT)    Function ReverseOtherMethod( ByVal Num_ As ULongInt ) As ULongInt        Dim as ULongInt reverse_ = 0        Dim As String numString_ = Str(Num_)        Dim As String tempString = ""               For _i As UInteger = Len(numString_) To 1  Step -1             numString_ = Left(numString_, _i)             tempString &= Right(numString_, 1)        Next _i               reverse_ = CULngInt(tempString)               Return reverse_    End Function 'ULONGINT := ReverseOtherMethod(ULONGINT)    ''_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_        Cls '<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<  USE CLS        Randomize Timer    Dim As String _inkey = ""    Dim As Double t1_ = 0    Dim As Double t2_ = 0    Dim As ULongInt number_ , reverse_    Do        cls        number_ = 1e+9 + CULngInt (Rnd * 109999999900000000)               Locate 2, 4 : ? "  +--------+"        Locate 3, 4 : ? " / NUMBER /" & Space(10) & number_        Locate 4, 4 : ? "+--------+ "               Locate 6, 4 : ? "  +---------+"        Locate 7, 4 : ? " / REVERSE /"        Locate 8, 4 : ? "+---------+ "                t1_ = Timer         reverse_ = ReverseIRCVS( number_ )         t1_ = Timer - t1_         Locate 7, 4 : ? Tab(19); "IRCVS "; reverse_         Locate 8, 4 : ? Tab(24); t1_  * 1e+6                t2_ = Timer         reverse_ = ReverseOtherMethod( number_ )         t2_ = Timer - t2_         Locate 10, 4 : ? Tab(19); "Other ";  reverse_         Locate 11, 4 : ? Tab(24); t2_ * 1e+6                ? : ? : ? "    Time ratio : "; t2_ / t1_                ? : ? : ? "    [SPACE] to pause, then [ESC]x2 to quit"         _inkey = Inkey         Sleep 2000         Sleep -(InKey=Chr(32))*15000           Loop Until _inkey = Chr(27)    ? "END"    Sleep : End    ''_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_     `

regards
Zippy
Posts: 1295
Joined: Feb 10, 2006 18:05

### Re: Reverse a number

@Tourist Trap

Here's another method of string reversal, this using string indexing and swap():

Code: Select all

`'revNum - string reverse...'dim as integer a,lsdim as ulongint tndim as double bt,et dim as string ts'tn = 1e+9 + CULngInt (Rnd * 109999999900000000)'ts=str(tn)ls=len(ts)'print ts'bt=timerfor a=ls to int(.5*ls)+1 step -1   swap ts[a-1],ts[ls-a]Nextet=timer'print ts,et-bt'sleep`

This is essentially instantaneous in action [on a 3.60GHz I7].
dodicat
Posts: 6247
Joined: Jan 10, 2006 20:30
Location: Scotland

### Re: Reverse a number

lrcvs
Your method beats string reversal, but it can be optimized slightly.
For instance N * 10 = N*8 + N*2 which is optimised automatically by FB.
You can shave off another sliver if you write in the two shl's yourself.

Code: Select all

` function _reverse_(n as ulongint) as ulongintvar s=str(n)var lens=len(s)for n as integer=0 to (lens-1)\2:swap s[n],s[lens-1-n]:next    return valulng(s)end functionFunction ReverseIRCVS( ByVal Num_ As ULongInt ) As ULongInt    Dim As ULongInt temp_ = Num_    Dim as ULongInt reverse_ = 0        '::::::::::::::::::::::::::::::::::::::::::::::::   'Reverse a number !!!        While temp_ <> 0          reverse_ = (reverse_ * 10) + (temp_ Mod 10)          temp_ = Int(temp_/10)          Wend    '::::::::::::::::::::::::::::::::::::::::::::::::       Return reverse_End Function 'ULONGINT := ReverseIRCVS(ULONGINT)Function ReverseIRCVS2( ByVal Temp_ As ULongInt ) As ULongInt    'Dim As ULongInt temp_ = Num_    Dim as ULongInt reverse_ '= 0        '::::::::::::::::::::::::::::::::::::::::::::::::   'Reverse a number !!!        While temp_ <> 0         reverse_= reverse_ shl 3+reverse_ shl 1  + (temp_ Mod 10) '=  reverse_*8 +  reverse_ * 2          temp_ =temp_\10         Wend    '::::::::::::::::::::::::::::::::::::::::::::::::       Return reverse_End Functiondim as ulongint n=1844674407370955161randomize 1dim as ulongint tmpdo    print "Number is "; n    printdim as double t=timerfor z as integer=1 to 100000tmp =reverseIRCVS2(n)next zprint timer-t,tmpsleep 50t=timerfor z as integer=1 to 100000tmp =reverseIRCVS(n)next zprint timer-t,tmpsleep 50for z as integer=1 to 100000tmp =_reverse_(n)next zprint timer-t,tmpprintn=rnd*1844674407370955161sleep 500loop until inkey=chr(27)sleep`
fxm
Posts: 9529
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

### Re: Reverse a number

@Zippy

When there is an odd number of characters, it's not useful to swap the centrally character with itself:

Code: Select all

`for a=ls to int(.5*(ls+1))+1 step -1   swap ts[a-1],ts[ls-a]Next`
lrcvs
Posts: 575
Joined: Mar 06, 2008 19:27
Location: Spain

### Re: Reverse a number

Hi, Zippy:

Your method is also very fast.
Here are the comparison:

Code: Select all

`    '    'Prog to compare 2 number-reversion methods    '    Function ReverseIRCVS( ByVal Num_ As ULongInt ) As ULongInt        Dim As ULongInt temp_ = Num_        Dim as ULongInt reverse_ = 0               '::::::::::::::::::::::::::::::::::::::::::::::::       'Reverse a number !!!            While temp_ <> 0              reverse_ = (reverse_ * 10) + (temp_ Mod 10)              temp_ = Int(temp_/10)              Wend        '::::::::::::::::::::::::::::::::::::::::::::::::              Return reverse_    End Function 'ULONGINT := ReverseIRCVS(ULONGINT)    Function ReverseOtherMethod( ByVal Num_ As ULongInt ) As ULongInt        Dim as ULongInt reverse_ = 0        Dim As String numString_ = Str(Num_)        Dim As String tempString = ""               For _i As UInteger = Len(numString_) To 1  Step -1             numString_ = Left(numString_, _i)             tempString &= Right(numString_, 1)        Next _i               reverse_ = CULngInt(tempString)               Return reverse_    End Function 'ULONGINT := ReverseOtherMethod(ULONGINT)        Function ReverseZippy( ByVal Num_ As ULongInt ) As string 'Zippy        dim as integer a,ls    dim as ulongint tn    dim as string ts    '    tn = Num_    ts=str(tn)    ls=len(ts)    for a=ls to int(.5*ls)+1 step -1        swap ts[a-1],ts[ls-a]    Next     ReverseZippy = ts    End Function 'Zippy    ''_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_        Cls '<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<  USE CLS        Randomize Timer    Dim As String _inkey = ""    Dim As Double t1_ = 0    Dim As Double t2_ = 0    Dim As Double t3_ = 0       Dim As ULongInt number_ , reverse_    Dim as string Zippy_reverse        Do        cls        number_ = 1e+9 + CULngInt (Rnd * 109999999900000000)               Locate 2, 4 : ? "  +--------+"        Locate 3, 4 : ? " / NUMBER /" & Space(10) & number_        Locate 4, 4 : ? "+--------+ "               Locate 6, 4 : ? "  +---------+"        Locate 7, 4 : ? " / REVERSE /"        Locate 8, 4 : ? "+---------+ "                t1_ = Timer         reverse_ = ReverseIRCVS( number_ )         t1_ = Timer - t1_         Locate 7, 4 : ? Tab(19); "IRCVS "; reverse_         Locate 8, 4 : ? Tab(24); t1_  * 1e+6                t2_ = Timer         reverse_ = ReverseOtherMethod( number_ )         t2_ = Timer - t2_         Locate 10, 4 : ? Tab(19); "Other ";  reverse_         Locate 11, 4 : ? Tab(24); t2_ * 1e+6                t3_ = Timer         Zippy_reverse = ReverseZippy( number_ )         t3_ = Timer - t3_         Locate 14, 4 : ? Tab(19); "Zippy ";  Zippy_reverse         Locate 15, 4 : ? Tab(24); t3_ * 1e+6                  _inkey = Inkey         Sleep 2000         Sleep -(InKey=Chr(32))*15000           Loop Until _inkey = Chr(27)    ? "END"    Sleep : End    ''_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_     `

I believe that by working both with chains, going slower.

Moreover, if you observe, if the number is: 1234560, your result is: 0654321 <<< is not a number, it's a chain.

Regards
fxm
Posts: 9529
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

### Re: Reverse a number

fxm wrote:@Zippy

When there is an odd number of characters, it's not useful to swap the centrally character with itself

lrcvs wrote:Hi, Zippy:

Your method is also very fast.
Here are the comparison
.....
I believe that by working both with chains, going slower.

Moreover, if you observe, if the number is: 1234560, your result is: 0654321 <<< is not a number, it's a chain.

With the 2 remarks corrected:

Code: Select all

`   '    'Prog to compare 2 number-reversion methods    '    Function ReverseIRCVS( ByVal Num_ As ULongInt ) As ULongInt        Dim As ULongInt temp_ = Num_        Dim as ULongInt reverse_ = 0               '::::::::::::::::::::::::::::::::::::::::::::::::       'Reverse a number !!!            While temp_ <> 0              reverse_ = (reverse_ * 10) + (temp_ Mod 10)              temp_ = Int(temp_/10)              Wend        '::::::::::::::::::::::::::::::::::::::::::::::::              Return reverse_    End Function 'ULONGINT := ReverseIRCVS(ULONGINT)    Function ReverseOtherMethod( ByVal Num_ As ULongInt ) As ULongInt        Dim as ULongInt reverse_ = 0        Dim As String numString_ = Str(Num_)        Dim As String tempString = ""               For _i As UInteger = Len(numString_) To 1  Step -1             numString_ = Left(numString_, _i)             tempString &= Right(numString_, 1)        Next _i               reverse_ = CULngInt(tempString)               Return reverse_    End Function 'ULONGINT := ReverseOtherMethod(ULONGINT)       Function ReverseZippy( ByVal Num_ As ULongInt ) As ULongInt 'Zippy        dim as integer a,ls    dim as ulongint tn    dim as string ts    '    tn = Num_    ts=str(tn)    ls=len(ts)    for a=ls to int(.5*(ls+1))+1 step -1        swap ts[a-1],ts[ls-a]    Next     ReverseZippy = culngInt(ts)    End Function 'Zippy    ''_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_       Cls '<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<  USE CLS       Randomize Timer    Dim As String _inkey = ""    Dim As Double t1_ = 0    Dim As Double t2_ = 0    Dim As Double t3_ = 0      Dim As ULongInt number_ , reverse_       Do        cls        number_ = 1e+9 + CULngInt (Rnd * 109999999900000000)               Locate 2, 4 : ? "  +--------+"        Locate 3, 4 : ? " / NUMBER /" & Space(10) & number_        Locate 4, 4 : ? "+--------+ "               Locate 6, 4 : ? "  +---------+"        Locate 7, 4 : ? " / REVERSE /"        Locate 8, 4 : ? "+---------+ "                t1_ = Timer         reverse_ = ReverseIRCVS( number_ )         t1_ = Timer - t1_         Locate 7, 4 : ? Tab(19); "IRCVS "; reverse_         Locate 8, 4 : ? Tab(24); t1_  * 1e+6                t2_ = Timer         reverse_ = ReverseOtherMethod( number_ )         t2_ = Timer - t2_         Locate 10, 4 : ? Tab(19); "Other ";  reverse_         Locate 11, 4 : ? Tab(24); t2_ * 1e+6                t3_ = Timer         reverse_ = ReverseZippy( number_ )         t3_ = Timer - t3_         Locate 14, 4 : ? Tab(19); "Zippy ";  reverse_         Locate 15, 4 : ? Tab(24); t3_ * 1e+6                  _inkey = Inkey         Sleep 2000         Sleep -(InKey=Chr(32))*15000           Loop Until _inkey = Chr(27)    ? "END"    Sleep : End    ''_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_    `
lrcvs
Posts: 575
Joined: Mar 06, 2008 19:27
Location: Spain

### Re: Reverse a number

Hi, dodicat:

Waw..., "You broke the sound barrier at speed"

Here is a sample:

Code: Select all

`Number is 1844674407370955161 0.1821999723416301         1615590737044764481 0.204180419579199          1615590737044764481 0.5653059257538668         1615590737044764481Number is 874575150437315306 0.1663091258794207         603513734051575478 0.1782519845382122         603513734051575478 0.5209483328171132         603513734051575478Number is 981827202006279701 0.1643644653154084         107972600202728189 0.1778276289291902         107972600202728189 0.5188307452470475         107972600202728189Number is 1182109933128751415 0.171086269345416          5141578213399012811 0.1877397825705387         5141578213399012811 0.5491041459183936         5141578213399012811Number is 1814227019137390850 0.1712597550787862         580937319107224181 0.1856604680187921         580937319107224181 0.5339997122523474         580937319107224181Number is 424710689916767401 0.1592023567229628         104767619986017424 0.1753119460710106         104767619986017424 0.5188198500085228         104767619986017424Number is 1267509344855497008 0.1722068028216093         8007945584439057621 0.1867485951431274         8007945584439057621 0.5349213377682371         8007945584439057621Number is 869672234386037073 0.1652237924087725         370730683432276968 0.1782463972391888         370730683432276968 0.5199423390418474         370730683432276968`

I've never worked with "shl" is not to be served.
I know that you write underscore "XXX_"

Regards
Zippy
Posts: 1295
Joined: Feb 10, 2006 18:05

### Re: Reverse a number

fxm wrote:@Zippy

When there is an odd number of characters, it's not useful to swap the centrally character with itself:

Code: Select all

`for a=ls to int(.5*(ls+1))+1 step -1   swap ts[a-1],ts[ls-a]Next`

Yes, the middle character of an odd-length string is unnecessarily swapped.

The simplest fix was ugly, leaving a float terminating an integer-based loop.

Code: Select all

`'for a=ls to int(.5*ls)+1 step -1for a=ls to .5*ls+1 step -1`

and this MAY be slower, hard to tell. I'd rather swap the central char.

=====

Note that I posted code as an example of "string reversal" using indexing, addressed specifically to Tourist Trap. It's obviously too expensive to convert numbers to/from strings, I'm not advocating string reversal for reversing numbers.
.
D.J.Peters
Posts: 8023
Joined: May 28, 2005 3:28
Contact:

### Re: Reverse a number

Code: Select all

`type NUMBER as ULONGINTFunction Reverse(n As NUMBER) As NUMBER  dim as NUMBER r,t  if n<10 then return n  do    t     = r    t shl = 1    r shl = 3    r  +  = t    t     = n \ 10    n  -  = t * 10    r  +  = n    n     = t  loop while n  return rEnd Functionprint 8,reverse(8)print 128,reverse(128)print 123456789,reverse(123456789)print 987654321,reverse(987654321)sleep`
lrcvs
Posts: 575
Joined: Mar 06, 2008 19:27
Location: Spain

### Re: Reverse a number

Hi, D.J.Peters

Thank you very much!

With your example, and the example of dodicat, and the handbook of examples of FB, I understood that it serves "SHL".

Regards
Tourist Trap
Posts: 2817
Joined: Jun 02, 2015 16:24

### Re: Reverse a number

Zippy wrote:Note that I posted code as an example of "string reversal" using indexing, addressed specifically to Tourist Trap.

This is a nice example.

Code: Select all

`''''Transforms num in an array of digits''   Cls    Dim As Double t_ = Timer''--------------------------------------------------------Dim As ULongInt num = 18497130712345637Dim As UInteger lenNum = Len(Str(num))Dim As UByte numdigitArray(1 To Len(Str(num)))Dim As ULongInt _10expLenNum = 10^LenNumDim As ULongInt _sum = 0For _i As UInteger = 1 To lenNum   If _i > 1 Then  _sum = (numdigitArray(_i-1) + _sum)*10    numdigitArray(_i) = Int(10^_i*num/_10expLenNum) - _sumNext _it_ = (Timer - t_)*1e+6''--------------------------------------------------------   ''Display num as a single block    ? "num = "; num    ? "length num = "; lenNum   ''Display as array of digits    ? Chr(10) & "array = ";   For _i As Integer = 1 To lenNum       ? numdigitArray(_i) ;   Next _i    ?    ? "time to get the number as an array of digit = "; t_''''Reverse the array of digits''    t_ = Timer''--------------------------------------------------------Dim As UByte digitTemp For _i As Integer = 1 To lenNum/2    digitTemp = numdigitArray(_i)    numdigitArray(_i) = numdigitArray(lenNum + 1 - _i)    numdigitArray(lenNum + 1 - _i) = digitTempNext _it_ = (Timer - t_)*1e+6''--------------------------------------------------------   ''Display reversed array of digits    ? Chr(10) & "reverse = ";   For _i As Integer = 1 To lenNum       ? numdigitArray(_i) ;   Next _i    ?     ? "time to get the array reversed = "; t_Sleep : End'*`

[edited to add a new question but posted elsewhere....]
Last edited by Tourist Trap on Jan 11, 2017 15:32, edited 2 times in total.