C++ 减少C+中双精度的位数+;
我需要一个函数来降低我的双精度(位数) 我需要它来计算,而不是在屏幕上输出 到目前为止,我得到的是:C++ 减少C+中双精度的位数+;,c++,function,double,precision,digit,C++,Function,Double,Precision,Digit,我需要一个函数来降低我的双精度(位数) 我需要它来计算,而不是在屏幕上输出 到目前为止,我得到的是: double setDigits(double _number, int _digits) { double tenth = pow((double)10,_digits); _number *= tenth; _number = floor(_number); _number /= tenth; return _number; } 调用setDigi
double setDigits(double _number, int _digits)
{
double tenth = pow((double)10,_digits);
_number *= tenth;
_number = floor(_number);
_number /= tenth;
return _number;
}
调用setDigits(sqrt(2,3)
得到1.4139999999999,而不是我想要的1.414
我能做什么?试试这个:
double setDigits(double _number, int _digits)
{
double tenth = pow((double)10,_digits);
return floor(_number * tenth + 0.5)/tenth;
}
std::cout<<setDigits(sqrt(2),3);
双位设置数字(双位数字,整数)
{
十分之二=功率((双)10,_位数);
返回层(_编号*第十层+0.5)/第十层;
}
标准::cout
我能做什么
不幸的是,根本问题没有解决:在您的平台中,1.414没有精确的双精度表示。您不能使用“1.414”运行计算,因为您不能将“1.414”放在双精度
中的任何位置
例如,见
您可以做的是保持数字的最大精度,并降低显示精度。您需要计算机器精度,并在计算过程中跟踪误差
因此,您将使用1.413999999997,并在最后得到一个答案,例如,41.99999137;您将使用它来显示
printf("The answer is %.3f\n", theAnswer);
或者您可以更改平台(编译器、数学库或浮点表示,例如在支持的情况下使用long double
),但请记住,您可以获得正确的1.414,代价是获得错误的1.873(将其设为1.872999999或1.87300000001),并且计算将或多或少具有相同的错误
您可以使用整数算术,将初始数字乘以1000000(得到1414000)或其他合适的比例,然后在末尾除法。但整数有一个最大界限
还有一些任意精度库,它们使用不同的内部表示形式,并允许您以所需的方式指定精度,例如GMP()。当然,处理这个问题比具体说明更困难
op1 = 6.0;
op2 = 7.0;
theAnswer = op1 * op2;
而且处理速度也比较慢,但结果很好——或者说是你告诉他们的那样好。以下几行是无效的
double tenth = pow((double)10,_decimals); //_decimals is not declared
_number = floor(_digits); //should be floor(_number)
修正后的函数为
double setDigits(double _number, int _digits)
{
double tenth = pow((double)10,_digits);
_number *= tenth;
_number = floor(_number);
_number /= tenth;
return _number;
}
您可以创建一个中间类,该类以int
的形式在内部管理数据,但以double的形式进行输入和输出:
class TruncatedDouble
{
private:
int value_;
public:
TruncatedDouble(double d) : value_((int)(double * 1000)) {}
void SetValue(double d) {value_ = (int)(double * 1000);}
double GetValue() {return (double)value_ / 1000;}
};
您还必须使所有常用的操作符过载,但这很容易。例如:
TruncatedDouble& operator+=(const TruncatedDouble& rh) {value_ += rh.value_;}
等等。这个类实际上相当快,因为您使用的是int
而不是double
,并且您永远不会失去精度
double setDigits(double _number, int _digits)
{
double tenth = pow((double)10,_digits);
int result = (_number * tenth) + 0.5;
double aux = result / tenth;
return aux;
}
用第十个=1000尝试下列方法
result = 1413,9999999999999 * 1000 +0,5
result = 1414,4......
result = 1414
我不知道你可能不会检查这个答案,但其他人会检查
我是C++新手,但我找到了一个方法来做这个
double Point::norm()
{
}
我用这个,但你可以自己写数学课来做1e-16的差异在你的计算中真的很显著吗?1.414没有精确的二进制表示,所以当你使用它时,它永远不会是1.414。所以如果1E-16的错误是不可接受的,你应该去四元精度。你应该认真考虑浮点如何工作,以及这是否会为你工作。不能保证您可以用二进制浮点表示期望的数字。例如,如果你在使用货币,考虑只使用整数和存储美分而不是美元。“代码> >小数部分<代码>是从哪里来的?目的是在比较值时使用它,因此,不必知道确切的数字(我的一些数字在1E-7中推迟,并且这种精度不相关),我会绕过它们。为了便于比较
使用浮点数解决了我的问题。@user1595420:浮点数就是这样工作的。看起来漂亮的数字不能存储漂亮,反之亦然。这是一个十进制读取和二进制存储的问题。我已经在我的程序中写了这个,但是在我的帖子中失败了,因为我重命名了一些变量以使它更易于阅读。我发现如果我把所有的双打都改成浮动,效果会很好。因此,由于我不需要双精度,所以没有问题。请参阅我附带的演示。干杯。:)非常有帮助,你让我意识到我不需要双精度。将我所有的双打改为浮点数纠正了这些奇怪的值。好的,但请记住,您选择了“更改平台”选项;你注意到的效果仍然存在,只是数字不同。嗯,是的,你会失去精确度。任何小数点右边超过四位数的值都将被截断,正如此类名称所示。@PeteBecker:我的意思是,您不会因为操作中的舍入而失去精度,因为您将使用int
s进行操作。根据问题,丢失小数点右边超过四位的数字不是缺点,而是要求。当然,您可以舍入而不是截断;为了简单起见,我用了截断法,但四舍五入并不难。是的,我有点迟钝。很抱歉
return (double)floor((sqrt(pow(px,2)+pow(py,2)+pow(pz,2))*1000))*0.001;