C ++:如何在没有舍入,截断或填充的情况下从Float转换为String?

时间:2009-06-18 05:26:11

标签: c++ floating-point

我遇到问题,无法解决问题。需要大师的帮助。以下是示例代码: -

float f=0.01f;
printf("%f",f);

如果在调试期间检查变量中的值,则f包含'0.0099999998'值,printf的输出为0.010000。

一个。有没有办法可以强制编译器为float类型的变量赋值相同的值?

湾我想将float转换为字符串/字符数组。怎么可能只将完全相同的值转换为字符串/字符数组。我想确保没有填充零,没有填充不需要的值,数字没有变化,如上例所示。

10 个答案:

答案 0 :(得分:6)

除了极少数的值(例如0.25)之外,不可能使用基数2值准确地表示基数10十进制数。要获得所需,您必须从float / double内置类型切换到某种十进制数字包。

答案 1 :(得分:3)

您可以这样使用boost::lexical_cast

float blah = 0.01;
string w = boost::lexical_cast<string>( blah );

变量w将包含文本值0.00999999978。但是我不知道你什么时候需要它。

最好使用boost::format将float格式化为字符串。以下代码显示了如何执行此操作:

float blah = 0.01;
string w = str( boost::format("%d") % blah ); // w contains exactly "0.01" now

答案 2 :(得分:2)

看看这个 C++ reference。特别是关于精度的部分:

float blah = 0.01;
printf ("%.2f\n", blah);

答案 3 :(得分:2)

有无数的实数。

数据类型floatdoublelong double只能使用有限数量的值。

也就是说,使用这些数据类型无法准确表示许多实数。

答案 4 :(得分:1)

Mark Ransom的帖子很好地解释了调试器为您提供不同值的原因。

关于打印一个没有舍入,截断和更精确的浮点数,你缺少精度说明符 - printf的默认精度通常是6个小数位。

尝试以下方法以获得10位数的精度:

float amount = 0.0099999998;
printf("%.10f", amount); 

作为旁注,更多C ++方式(与C风格)做事情是用cout:

float amount = 0.0099999998;
cout.precision(10);
cout << amount << endl;

答案 5 :(得分:1)

同样,你可以使用stdlib.h,有sprintfecvtfcvt函数(或者至少应该有!)。

int sprintf(char* dst,const char* fmt,...);

char *ecvt(double value, int ndig, int *dec, int *sign);

char *fcvt(double value, int ndig, int *dec, int *sign);

sprintf 返回它写入字符串的字符数,例如

float f=12.00;
char buffer[32];
sprintf(buffer,"%4.2f",f) // will return 5, if it is an error it will return -1

ecvt fcvt 将字符返回到静态字符*位置,其中包含数字的空终止十进制表示,没有小数点,最重要的数字首先是偏移量小数点存储在dec中,登录“sign”(1 = - ,0 = +)ndig是要存储的有效位数。如果dec <0,则必须使用-dec zeros pror填充小数点。我不确定,你不是在Windows7系统上工作(有时不会运行旧的DOS3程序)为Dos 3寻找TurboC版本2,仍有一两个下载可用,这是Borland的一个相对较小的程序是一个小的Dos C / C ++编辑/编译器,甚至还附带了TASM,16位机器代码386/486编译,它包含在帮助文件中,还有许多其他有用的信息块。

所有三个例程都在“stdlib.h”中,或者应该是,虽然我发现在VisualStudio2010上它们不是标准的,经常超载处理WORD大小字符的函数,并要求你使用它自己的特定函数代替......“对于标准库来说太多了,”我几乎每次都嘀咕着自己,“也许他们出去找一本更好的字典!”

答案 6 :(得分:1)

实际上使用浮点处理器或协处理器或芯片本身的部分(大多数现在已集成到CPU中),永远不会产生准确的数学结果,但它们确实提供了相当粗略的精度,更准确结果,你可以考虑定义一个类“DecimalString”,它使用nybbles作为十进制字符和符号...并尝试使用字符串模拟基数10数学...在这种情况下,取决于你想要制作字符串的时间,你甚至可以完全取消指数部分一个字符串256可以用实际ASCII代表1x10 ^ -254到1 ^ + 255的直线小数,如果你想要一个符号则更短,但这可能会明显变慢。您可以通过反转数字顺序来加快速度,因此从左到右读取它们 单位,数十,数百,数千....

简单示例 例如。 “0021”变为1200 这需要左右“移动”以使小数点在例程之前排成一行,最好的选择是从ADD和SUB函数开始,然后在MUL和DIV函数中构建它们。如果你在一台大型机器上,只要你的心愿意,你就可以在理论上制造它们!

答案 7 :(得分:0)

您需要查阅平台标准以确定如何最好地确定正确的格式,您需要将其显示为* b ^ C,其中'a'是保持符号的整体组件,'b'是实现定义的(可能由标准修复),'C'是用于该数字的指数。

或者,你可以只用十六进制显示它,但它对人类没有任何意义,并且它仍然是二进制的,用于所有实际目的。 (同样便携!)

答案 8 :(得分:0)

回答你的第二个问题:

可以准确无误地将浮点数表示为字符串。但是,这需要十六进制表示。例如,1/16 = 0.1和10/16是0.A。

使用十六进制浮点数,您可以定义规范表示。我个人使用表示底层位数的固定位数,但您也可以决定去除尾随零。对于哪些尾随数字为零,没有混淆。

由于表示是准确的,转换是可逆的:f==hexstring2float(float2hexstring(f))

答案 9 :(得分:0)

对于(b),你可以做

std::ostringstream os;
os << f;
std::string s = os.str();