整数在较高值时表现出奇怪的行为

Integers exhibit odd behavior at higher values

我在 C# 中创建了一个程序,用于将数字从一个基数转换为任何其他基数(例如 Base-10 = A in 中的 10 Base-11).

对于每个目标基地,程序似乎在某个点上产生了不准确的值。例如,当从 Base-10 转换为 Base-11 然后返回 Base-10 时,在任何等于或大于 45949729863572161 的值(巧合地等于 1116; 谁会想到?)。

为了进行转换,我首先将数字转换为 Base-10,然后转换为目标基数。我不知道这个错误的原因是什么

最有可能的罪魁祸首是主要方法。
A) Base-10

的方法
static string toBase10(string origVal, uint origBase)
{
    ulong result = 0;
    //Convert each character to base-ten so that base-ten arithmetic can be used
    ulong[] b10Array = charsToBase10Readable(origVal, findSubArray(origBase));

    //Run through each place value to convert entire number to base-ten
    for (uint n = 0; n < b10Array.Length; n++)
    {
        ulong val = b10Array[n];
        result += val * ((ulong)Math.Pow(origBase, b10Array.Length - n - 1));
    }

        return result.ToString();
    }
}

B) 从 Base-10

转换的方法
static string fromBase10(ulong num, uint targetBase)
{
    string result = string.Empty;
    //Generate the original base
    char[] targetBaseChars = findSubArray(targetBase);
    do
    {
        result = targetBaseChars[num % (ulong)targetBase] + result;
        num /= (ulong)targetBase;
    }
    while (num > 0);

    return result;
}

其他可能的方法

static char[] findSubArray(uint i)
{
    char[] subArray = new char[i];
    for (uint n = 0; n < i; n++)
    {
        subArray[n] = masterBase[n];
    }
    return subArray;
}

如果上述方法不是问题,我的转换代码的更扩展版本可作为 Github Gist

有什么问题吗?我怀疑它是否达到了 ulong's max,尽管除此之外我不确定。

感谢您的帮助!

我在 LINQPad (v4) 中尝试了 运行 您的代码,使用您将 45949729863572161 从 base 10 转换为 base 11 的测试用例,我得到了正确的答案 (10000000000000000),我使用 [=12 验证了这一点=].

我也尝试做同样的转换,将 1 添加到您的值(即 45949729863572162),我仍然得到正确答案(10000000000000001)。

因此,我认为您的问题的答案是行为并不像您认为的那样奇怪,或者您使用的是存在错误的旧版本编译器。


根据您的评论,问题似乎与 Math.Pow 功能有关。

Math.Pow(11, 16) 产生 45949729863572160 而不是 45949729863572161。当我输入这个时,我看到大师 (Eric Lippert) 已经回答了,所以我会让他解释为什么以及如何解决它:)

Math.Pow 以双精度计算。双打只有大约 16 位小数的精度;当数字大约为 10 到 16 时,您将开始累积表示错误。您的是哪个。

改用BigInteger.Pow()。它具有任意大的精度。

顺便说一下,您不是第一个发现将 11 的 16 次方变成双精度数的人:

https://math.stackexchange.com/questions/91583/implementing-fermats-primality-test/91584#91584