避免双变量中的垃圾零值

时间:2016-12-30 13:48:54

标签: c++ double

在我的下面的程序中,

main
{
  // value is 476 
  int value = 476;

  // here dimension shows as 0.100000001
  float dimension = 0.1f;



 /// Here I am expecting value as 47.6,
 /// But it gives value as 47.600002288818......
 double result = value * dimension;
}

我想将值直接保存在数据库中,那么是否有任何inbuild函数可以获得预期的值?

预计:47.6而不是47.600002288 .....

3 个答案:

答案 0 :(得分:3)

有几种方法,但在所有情况下,您都必须弄清楚并确定浮点值应表示的精度位数。 float表示"实际上是.1而不是0.100000001"。

一旦你决定,你的值应该有两位数的精度,有几种方法可以将它们四舍五入。一种简单的方法是使用流格式:

#include <sstream>
#include <iomanip>

std::ostringstream o;

    o << std::setiosflags(std::ios::fixed) << std::setprecision(2) << 0.1;

std::string s=o.str();

您现在可以找到&#34; 0.10&#34;在s

如果由于您正在进行的任何计算而不知道精确位数有多少,您唯一的选择是使用专用库进行固定精度算术like GMP

答案 1 :(得分:0)

实际上,浮点的尾数用二进制表示(基数2)。这样做的一个结果是0.1十进制(也就是分数1/10)无法用浮点精确表示。

原因与1/3无法在固定的小数位数中精确表示一样 - 它是一个无限重复的值0.3333333.....,并将其截断为有限数量的位置会引入错误。唯一的区别是1/10是基数2中无限重复的值。因此它不能用有限数量的二进制数字来表示。

显然,其他值会以这种方式受到影响(例如0.20.6等)。这些错误是浮点表示的固有属性....或者换句话说,浮点表示近似值(可能缺乏精度的值)。并且,在进行一系列计算时,值中的错误会传播。

由于无法在浮点(和其他值)中准确表示值0.1,因此无法将浮点值精确存储到数据库中并获得正好为{{的值1}}。

您可以尝试以限制输出精度的方式打印值,例如

0.1

请记住,这会控制#include <sstream> #include <iomanip> #include <string> std::ostringstream o; o << std::fixed << std::setprecision(2) << result; std::string s=o.str(); 的格式化方式(例如,在这种情况下输出为字符串)。它不会更改result的值。

从理论上讲,字符串result可以存储在您的数据库中....如果该字段表示字符串而不是数字值。

答案 2 :(得分:-1)

该值存储为47.600002288以获得精度,但是当您想要使用它时,您可以在浮点后使用N位数,例如,如果printf中的值为(47.600002288),则使用:

printf("%.2f\n", result);

这将打印47.60,注意.2%告诉格式化函数在浮点后打印2个数字。

请注意,您可以使用sprintf

将其直接打印到字符串中
char s= malloc(sizeof(char)*10);
sprintf(s, "%.2f\n", result);
//s contains "47.60"

在这种情况下,您必须知道我使用的malloc参数sizeof(char)*10这意味着字符长度必须小于或等于9(因为最后一个字符保留用于字符串结尾char { {1}})。