Click here to Skip to main content
15,883,883 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
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:

VB
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
Updated 7-Nov-17 9: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...

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
 
Share this answer
 
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).
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.
 
Share this answer
 
v2
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:
C#
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:
C#
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);
}
 
Share this answer
 
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.
I found this solution and working now. Thanks to Kornfeld Eliyahu Peter for contributions. ( On-What-Base-Do-You-Stand)

VB
 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
 
Share this answer
 
v5
Converted Kenneth Haugland's solution to vb.net for vb.net users.
VB
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
 
Share this answer
 
v4

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900