在我的下面的程序中,
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 .....
答案 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.2
,0.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}})。