我正在编写一些函数来转换整数的基数,我正在使用Ideone this code on ideone
虽然它在Ideone上工作正常,但在C :: B上它给出了输出484
。我正在使用-std=c++11
,即使没有它(或使用-std=c++0x
),输出仍然是不正确的。
那么代码或编译器有问题吗?
我在windows上使用mingw(gcc 4.7.1)
#include<iostream>
#include<cmath>
#define bigint long long unsigned int
bigint base(int numberOldBase, int newBase)
{
bigint numberNewBase = 0;
int digitCounter = 0, remainder[100];
while (numberOldBase)
{
remainder[digitCounter] = numberOldBase % newBase;
numberOldBase /= newBase;
digitCounter++;
}
for (int currentDigit = 0; currentDigit < digitCounter; currentDigit++)
{
numberNewBase += ((remainder[currentDigit]) * pow(10, currentDigit));
}
return numberNewBase;
}
int main()
{
std::cout << base(1025, 15);
return 0;
}
答案 0 :(得分:2)
不准确的原因是浮点数不准确,如果在某些时候得到484.99999995,则在转换为int
时会被截断为484。在这种情况下,你应该仅限于积分算术,因为它会更快并且摆脱浮动不准确性。
bigint curExp = 1;
for (int currentDigit = 0; currentDigit < digitCounter; currentDigit++)
{
numberNewBase += remainder[currentDigit] * curExp;
curExp *= 10;
}
更详细的分析
numberNewBase += ((remainder[currentDigit]) * pow(10, currentDigit));
被解释为
numberNewBase = (float)numberNewBase + (((float)remainder[currentDigit]) * pow(10, currentDigit));
导致添加小的和大的浮点数的情况(这导致更大的舍入误差。
numberNewBase += (int)((remainder[currentDigit]) * pow(10.0, currentDigit));
方法有助于通过在添加之前转换为int来缓解问题
numberNewBase = numberNewBase + (int)(((float)remainder[currentDigit]) * pow(10, currentDigit));
然而,使用top方法可以完全避免浮动转换。