Click here to Skip to main content
13,256,716 members (52,248 online)
Rate this:
 
Please Sign up or sign in to vote.
I want convert base 3 biginteger value to base 10, and convert base 3 again. How can i do?

I am using this code for that. But i am getting wrong result. This code working for short values eg("22222222210222211011111222")

What I have tried:

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim BigValue As BigInteger = BigInteger.Parse("22222222210222211011111222011100022001111")
    Dim TenBase As BigInteger = ToTenBase(BigValue, 3)
    Dim TenBaseByte As Byte() = TenBase.ToByteArray
    Dim TreeBase As String = FromTenBase(TenBase, 3)
    If BigValue.ToString <> TreeBase.ToString Then Stop 'Stopping here
End Sub
 
Function ToTenBase(ByVal BigValue As BigInteger, ByVal Base As BigInteger) As String
    Dim Result As BigInteger = 0
    Dim strValue = BigValue.ToString.ToCharArray
    For i As BigInteger = strValue.Count - 1 To 0 Step -1
        Dim d As BigInteger = strValue(i).ToString
        Dim counter As BigInteger = ((strValue.Count - 1) - i)
        Result = Result + d * (BigInteger.Pow(Base, counter))
    Next
    Return Result.ToString
End Function
 
Function FromTenBase(BigValue As BigInteger, Base As BigInteger) As String
    Dim Result As String = ""
    Dim Division As BigInteger = BigValue
    Dim Remaining As BigInteger
    Dim Dividing As BigInteger
 
    Do Until Division < Base
        Dividing = Division
        Division = BigInteger.Divide(Division, Base)
        Remaining = Dividing - Division * Base
        Result = Remaining.ToString & Result
    Loop
    Result = Division.ToString & Result
    Return BigInteger.Parse(Result).ToString
End Function
Posted 4-Nov-17 22:10pm
gacar236
Updated 7-Nov-17 10:09am
v3
Comments
Kornfeld Eliyahu Peter 5-Nov-17 3:19am
   
This may fit you: https://www.codeproject.com/Tips/1085580/On-What-Base-Do-You-Stand
CPallini 5-Nov-17 5:58am
   
My virtual 5 (as well an actual 5 at your tip).
Kornfeld Eliyahu Peter 5-Nov-17 6:04am
   
Thank you...
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 1

Why are you using strings? That's very wasteful and inefficient.
Instead, use the BigInteger Divide and Modulus operations to extract each digit one at a time, and include it in a running total:
set powerOf = 1
set total = 0
while input not zero
   extract lowest digit using modulus 10
   multiply digit by powerOf
   add to total
   multiply powerOf by base
   divide input by 10
  Permalink  
Comments
CPallini 5-Nov-17 5:56am
   
Why are you using strings? That's very wasteful and inefficient.
The OP has to (unless I am missing something). I mean both 'parseFromBase3String' and 'FormatToBase3String' must be provided (since BigIteger doesn't not provide them).
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 3

Your code is a mess of cascading conversions, you need to check that every conversion works as expected, use the debugger to do so.
BigValue and TenBase are BigInteger, and you want
TenBase = ToTenBase(BigValue, 3)
see what you do with ToTenBase
ToTenBase does BigValue as BigInteger => ToString => ToCharArray => ToString => ToBigInteger => ToString => ToBigInteger
advice: you have BigInteger, you want BigInteger, stay BigInteger.
-----
There is a rather simple way to extract digits from a number without convertion to string
BI = 22222222210222211011111222011100022001111
Un = BI % 10 = 1
Tn = BI / 10 = 2222222221022221101111122201110002200111
repeat operation for each digit you need.
-----
There is a tool that allow you to see what your code is doing, its name is debugger. It is also a great learning tool because it show you reality and you can see which expectation match reality.
When you don't understand what your code is doing or why it does what it does, the answer is debugger.
Use the debugger to see what your code is doing. Just set a breakpoint and see your code performing, the debugger allow you to execute lines 1 by 1 and to inspect variables as it execute.

Debugger - Wikipedia, the free encyclopedia[^]
Visual Basic / Visual Studio Video Tutorial - Basic Debugging - YouTube[^]
Visual Basic .NET programming for Beginners - Breakpoints and Debugging Tools[^]
The debugger is here to show you what your code is doing and your task is to compare with what it should do.
There is no magic in the debugger, it don't find bugs, it just help you to. When the code don't do what is expected, you are close to a bug.
  Permalink  
v2
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 4

Have you heard of Horner's method[^]? It can remove the need to take the power of numbers, and you generally don't want to do that, since it is very slow.

The call and check code is:
string input = "22222222210222211011111222011100022001111";
string Base = "012";
BigInteger base10number = ToBase10Horner(input, Base);
var output = FromBase10(base10number, Base);
var IsTheSameNumber = input.Equals(output.ToString());
What I did was the following code:
        static string FromBase10(BigInteger value, string BaseChars)
        {
            int sign = 1;
            if (value < 0)
            {
                sign = -1;
            }
            else if (value == 0)
            {
                return BaseChars.ToCharArray()[0].ToString();
            }
            value *= sign;
     
            StringBuilder Result = new StringBuilder();
            int nBase = BaseChars.Length;
            BigInteger Reminder = value;
 
            do
            {          
                BigInteger ModnBase = (Reminder % nBase);
                Result.Append(BaseChars.ToCharArray()[(int)ModnBase]);
                Reminder /= nBase;
            } while (Reminder != 0);
            if (sign == -1)
                Result.Append('-');
 
            char[] charArray = Result.ToString().ToCharArray();
            Array.Reverse(charArray);
            return new string(charArray);           
        }
 
        static BigInteger ToBase10Horner(string Value, string BaseChars)
        {
            BigInteger nBase = BaseChars.Length;
            int count = Value.Length - 1;
            BigInteger nResult = 0;
 
            for (int i = 0; i < count; i++)
            {
                nResult = nBase * (nResult + (BigInteger)BaseChars.ToUpper().IndexOf(Value.ToCharArray()[i]));
            }
 
            nResult += (BigInteger)BaseChars.ToUpper().IndexOf(Value.ToCharArray()[count]);
 
            return (nResult);
        }
  Permalink  
v2
Comments
gacar 6-Nov-17 11:19am
   
Thanks for solution. No i didn't hear this method before. But i tried this method and i got error again. This method working on short biginteger values but getting error with long values.
Kenneth Haugland 6-Nov-17 17:24pm
   
I got it working for all the cases in C#. It returns the input perfectly.
gacar 7-Nov-17 6:16am
   
Did you test values to back base again? If then can you share "Ten Base to Other" method, please.
gacar 7-Nov-17 14:51pm
   
Yes, really working under vb.net now. Thanks for solution. I gave 5 stars and accepted solution. Because i calculate elepsed times between, your solution elepsed "0" milisecond :) , my solution elepsed "1" milisecond . Really very speed.
Kenneth Haugland 7-Nov-17 16:11pm
   
You should look at Ticks instead of milliseconds. I found that the Horners method was roughly twice as fast as the Pow methods.
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 2

I found this solution and working now. Thanks to Kornfeld Eliyahu Peter for contributions. ( On-What-Base-Do-You-Stand)

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim BigValue As BigInteger = BigInteger.Parse("22222222210222211011111222011100022001111")
        Dim TenBase As BigInteger = ToTenBase(BigValue, 3)
        Dim TenBaseByte As Byte() = BigValue.ToByteArray
        Dim TreeBase As BigInteger = FromTenBase(TenBase, 3)
        If BigValue.ToString <> TreeBase.ToString Then Stop 
    End Sub
 
   Function ToTenBase(ByVal BigValue As BigInteger, ByVal Base As Integer) As BigInteger
        Dim Total As BigInteger
        Dim str As String = BigValue.ToString
        str = StrReverse(str)
        For i As Integer = str.Length - 1 To 0 Step -1
            Dim k As Integer = Microsoft.VisualBasic.Val(str(i))
            Total = Total + k * (Base) ^ i
        Next
        Return Total
    End Function
 
    Function FromTenBase(BigValue As BigInteger, Base As Integer) As BigInteger
        Dim BigByte() As Byte = BigValue.ToByteArray
        Dim Remaining As Numerics.BigInteger = BigValue
        Dim Count As Integer = Fix(Math.Log(BigValue, Base))
        Dim Result(Count) As Byte
        Do Until Remaining <= 0
            Dim Pow As Integer = Fix(Math.Log(Remaining, Base))
            Dim Division As BigInteger = Remaining / Base ^ Pow
            Result(Pow) = Division
            Remaining = Remaining - (Division* Base ^ Pow)
        Loop
        Array.Reverse(Result)
        Return BigInteger.Parse(ArrayToString(Result))
    End Function
 
    Function ArrayToString(ByVal Arr As Array) As String
        Dim s As String
        For i As Integer = 0 To Arr.Length - 1
            s = s & Arr(i)
        Next
        Return s
    End Function
  Permalink  
v5
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 5

Converted Kenneth Haugland's solution to vb.net for vb.net users.
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 
        Dim input As String = "222222222102222110111112220111000220011110000011112222101111222011"
        Dim Base As String = "012"
        Dim base10number As BigInteger = ToBase10Horner(input, Base)
        Dim output = FromBase10(base10number, Base)
        Dim IsTheSameNumber = input.Equals(output.ToString())
    End Sub
     
    Private Shared Function FromBase10(value As BigInteger, BaseChars As String) As String
        Dim sign As Integer = 1
        If value < 0 Then
            sign = -1
        ElseIf value = 0 Then
            Return BaseChars.ToCharArray()(0).ToString()
        End If
        value *= sign
 
        Dim Result As New StringBuilder()
        Dim nBase As Integer = BaseChars.Length
        Dim Reminder As BigInteger = value
 
        Do
            Dim ModnBase As BigInteger = (Reminder Mod nBase)
            Result.Append(BaseChars.ToCharArray()(ModnBase))
            Reminder /= nBase
        Loop While Reminder <> 0
        If sign = -1 Then
            Result.Append("-"c)
        End If
 
        Dim charArray As Char() = Result.ToString().ToCharArray()
        Array.Reverse(charArray)
        Return New String(charArray)
    End Function
 
    Private Shared Function ToBase10Horner(Value As String, BaseChars As String) As BigInteger
        Dim nBase As BigInteger = BaseChars.Length
        Dim count As Integer = Value.Length - 1
        Dim nResult As BigInteger = 0
 
        Dim i As Integer = 0
        While i < count
            Dim bi As BigInteger = BaseChars.ToUpper().IndexOf(Value.ToCharArray()(i))
            nResult = nBase * (nResult + bi)
            System.Math.Max(System.Threading.Interlocked.Increment(i), i - 1)
        End While
        Dim co As BigInteger = BaseChars.ToUpper().IndexOf(Value.ToCharArray()(count))
        nResult += co
 
        Return (nResult)
    End Function
  Permalink  
v4

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month


Advertise | Privacy |
Web03 | 2.8.171114.1 | Last Updated 17 Nov 2017
Copyright © CodeProject, 1999-2017
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100