C# 从基数转换为十进制变得疯狂
C# Converting From Base to Decimal went Crazy
所以我想到了将任何基数转换为十进制(基数 10)的想法:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SoloLearn
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("What is the number you want to convert?");
string num = Console.ReadLine();
Console.WriteLine("In what base is this number?");
int mathBase = int.Parse(Console.ReadLine());
double output = 0;
int j = 0;
char[] nums = num.ToCharArray();
for(int i=num.Length - 1; i>=0; i--) {
output = output + Math.Pow(mathBase,i) * nums[j] * 1;
Console.WriteLine("i: " + i +", j:" + j + ", nums[j]: " + nums[j] + ", output: " + output + ", mathBase: " + mathBase + ", " + Math.Pow(mathBase,i) + ".");
j++;
}
Console.WriteLine("The number " + num + " in base 10 (Decimal) is " + output + ".");
Console.ReadLine();
}
}
}
所以我从二进制 (num = 100, mathBase = 2) 开始,但答案太疯狂了。这就是为什么我添加此代码以查看到底发生了什么:
Console.WriteLine("i: " + i +", j:" + j + ", nums[j]: " + nums[j] + ", output: " + output + ", mathBase: " + mathBase + ", " + Math.Pow(mathBase,i) + ".");
j++;
嗯,所有变量都是正确的:
所以是的,我真的不知道发生了什么,因为所有的计算似乎都是正确的(Math.Pow(mathBase,i) = 2^2 = 4
,如图所示,但是,4 * nums[j] = 4 * 1 = 196
?如果有人知道到底发生了什么,请告诉我!
你的问题是 nums
是 char[]
。因此 nums[j]
是一个字符。现在您看到的问题是 char 可以隐式转换为数字,但不是您想要的方式 - 它使用它的 ascii 值,所以 1 是 ascii 值 49,0 是 ascii 值 48。那时候数学全错了。
您需要做的是将您的输入字符串转换为一个整数数组,而不是一个字符数组。可能执行此操作的一些示例代码是:
int[] nums = num.Select(x=>x-'0').ToArray();
这样做是利用字符 0-9 是 ascii 48-57 的事实,如果你从每个字符中取出 ascii 0 (48),你将得到 0-9。它还利用了字符串也是 IEnumerable<char>
的事实,因此可以轻松地进行 LINQ。
通过此修改,您的程序应该可以按预期运行。
这里的 num[j] 是一个字符,所以你应该在任何计算之前把它转换成 int。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SoloLearn
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("What is the number you want to convert?");
string num = Console.ReadLine();
Console.WriteLine("In what base is this number?");
int mathBase = int.Parse(Console.ReadLine());
double output = 0;
int j = 0;
char[] nums = num.ToCharArray();
for(int i=num.Length - 1; i>=0; i--) {
output = output + Math.Pow(mathBase,i) * Int32.Parse(nums[j].ToString()) * 1;
Console.WriteLine("i: " + i +", j:" + j + ", nums[j]: " + nums[j] + ", output: " + output + ", mathBase: " + mathBase + ", " + Math.Pow(mathBase,i) + ".");
j++;
}
Console.WriteLine("The number " + num + " in base 10 (Decimal) is " + output + ".");
Console.ReadLine();
}
}
}
从任意基数转换时,您必须至少处理三个范围:
'0'..'9' corresponds to 0..9
'a'..'z' corresponds to 10..36
'A'..'Z' corresponds to 10..36
所以你必须在你的代码中插入:
for (int i=num.Length - 1; i>=0; i--) {
// actual char, say 'C'
int c = nums[j];
// corresponding integer value, 12
int v = 0;
if (c >= '0' && c <= '9')
v = c - '0';
else if (c >= 'a' && c <= 'z')
v = c - 'a' + 10;
else if (c >= 'A' && c <= 'Z')
v = c - 'A' + 10;
// please, notice not nums[j] but the value it corresponds to - v
output = output + Math.Pow(mathBase, i) * v;
...
}
P.S。在 Linq 的帮助下,您可以简明扼要:
string num = "abC02";
int mathBase = 16;
int result = num
.Select(c =>
c >= '0' && c <= '9' ? c - '0'
: c >= 'a' && c <= 'z' ? c - 'a' + 10
: c >= 'A' && c <= 'Z' ? c - 'A' + 10
: 0)
.Aggregate((s, a) => s * mathBase + a);
// 703490
Console.Write(result);
所以我想到了将任何基数转换为十进制(基数 10)的想法:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SoloLearn
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("What is the number you want to convert?");
string num = Console.ReadLine();
Console.WriteLine("In what base is this number?");
int mathBase = int.Parse(Console.ReadLine());
double output = 0;
int j = 0;
char[] nums = num.ToCharArray();
for(int i=num.Length - 1; i>=0; i--) {
output = output + Math.Pow(mathBase,i) * nums[j] * 1;
Console.WriteLine("i: " + i +", j:" + j + ", nums[j]: " + nums[j] + ", output: " + output + ", mathBase: " + mathBase + ", " + Math.Pow(mathBase,i) + ".");
j++;
}
Console.WriteLine("The number " + num + " in base 10 (Decimal) is " + output + ".");
Console.ReadLine();
}
}
}
所以我从二进制 (num = 100, mathBase = 2) 开始,但答案太疯狂了。这就是为什么我添加此代码以查看到底发生了什么:
Console.WriteLine("i: " + i +", j:" + j + ", nums[j]: " + nums[j] + ", output: " + output + ", mathBase: " + mathBase + ", " + Math.Pow(mathBase,i) + ".");
j++;
嗯,所有变量都是正确的:
所以是的,我真的不知道发生了什么,因为所有的计算似乎都是正确的(Math.Pow(mathBase,i) = 2^2 = 4
,如图所示,但是,4 * nums[j] = 4 * 1 = 196
?如果有人知道到底发生了什么,请告诉我!
你的问题是 nums
是 char[]
。因此 nums[j]
是一个字符。现在您看到的问题是 char 可以隐式转换为数字,但不是您想要的方式 - 它使用它的 ascii 值,所以 1 是 ascii 值 49,0 是 ascii 值 48。那时候数学全错了。
您需要做的是将您的输入字符串转换为一个整数数组,而不是一个字符数组。可能执行此操作的一些示例代码是:
int[] nums = num.Select(x=>x-'0').ToArray();
这样做是利用字符 0-9 是 ascii 48-57 的事实,如果你从每个字符中取出 ascii 0 (48),你将得到 0-9。它还利用了字符串也是 IEnumerable<char>
的事实,因此可以轻松地进行 LINQ。
通过此修改,您的程序应该可以按预期运行。
这里的 num[j] 是一个字符,所以你应该在任何计算之前把它转换成 int。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SoloLearn
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("What is the number you want to convert?");
string num = Console.ReadLine();
Console.WriteLine("In what base is this number?");
int mathBase = int.Parse(Console.ReadLine());
double output = 0;
int j = 0;
char[] nums = num.ToCharArray();
for(int i=num.Length - 1; i>=0; i--) {
output = output + Math.Pow(mathBase,i) * Int32.Parse(nums[j].ToString()) * 1;
Console.WriteLine("i: " + i +", j:" + j + ", nums[j]: " + nums[j] + ", output: " + output + ", mathBase: " + mathBase + ", " + Math.Pow(mathBase,i) + ".");
j++;
}
Console.WriteLine("The number " + num + " in base 10 (Decimal) is " + output + ".");
Console.ReadLine();
}
}
}
从任意基数转换时,您必须至少处理三个范围:
'0'..'9' corresponds to 0..9
'a'..'z' corresponds to 10..36
'A'..'Z' corresponds to 10..36
所以你必须在你的代码中插入:
for (int i=num.Length - 1; i>=0; i--) {
// actual char, say 'C'
int c = nums[j];
// corresponding integer value, 12
int v = 0;
if (c >= '0' && c <= '9')
v = c - '0';
else if (c >= 'a' && c <= 'z')
v = c - 'a' + 10;
else if (c >= 'A' && c <= 'Z')
v = c - 'A' + 10;
// please, notice not nums[j] but the value it corresponds to - v
output = output + Math.Pow(mathBase, i) * v;
...
}
P.S。在 Linq 的帮助下,您可以简明扼要:
string num = "abC02";
int mathBase = 16;
int result = num
.Select(c =>
c >= '0' && c <= '9' ? c - '0'
: c >= 'a' && c <= 'z' ? c - 'a' + 10
: c >= 'A' && c <= 'Z' ? c - 'A' + 10
: 0)
.Aggregate((s, a) => s * mathBase + a);
// 703490
Console.Write(result);