Click here to Skip to main content
13,734,713 members
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 21:10pm
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...
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 | Cookies | Terms of Service
Web04-2016 | 2.8.180920.1 | Last Updated 17 Nov 2017
Copyright © CodeProject, 1999-2018
All Rights Reserved.
Layout: fixed | fluid

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