C#和C/C+中二进制到浮点转换之间的差异+;

C#和C/C+中二进制到浮点转换之间的差异+;,c#,c++,c,.net,C#,C++,C,.net,在C/C++和C#中转换二进制数时,我们通过舍入得到两个不同的结果。 例如,让我们以100001000010110110000001011111为例,在C#中,我们会得到34.84448,而我们会得到34.844479,为什么会有这么小的差异? 转换为C#: 在C++中: int a = 1108041919; //The number that is being represented float f = *(float *)&a; 由于该值是相同的,我们可以猜测处理该值的打印函数可

在C/C++和C#中转换二进制数时,我们通过舍入得到两个不同的结果。 例如,让我们以
100001000010110110000001011111
为例,在C#中,我们会得到
34.84448
,而我们会得到
34.844479
,为什么会有这么小的差异? 转换为C#:

在C++中:

int a = 1108041919; //The number that is being represented
float f = *(float *)&a;

由于该值是相同的,我们可以猜测处理该值的打印函数可能是其中的细微差别:-)

有许多方法可以明确地表示十进制中的相同浮点值。例如,您可以在精确输出后添加任意多个零(请注意,由于2的每一次幂都有一个有限长度的十进制表示,所以每个浮点数都有一个有限长度的十进制表示)

“何时可以停止打印额外数字”的标准通常被选择为“如果您再次将十进制输出解析为浮点值,则当您将获得完全相同的值时,您可以停止打印额外数字”。简言之:输出一个浮点值是“往返”的

如果分析十进制表示法
34.844479
34.84448
,您会发现它们都转换回浮点值
0x420b60bf
0100000101101100000011111
。因此这两个字符串都表示相同的浮点数。(来源:自己试试)

您的问题归结为“为什么不同的运行库为同一个浮点打印不同的值?”,答案是“通常由库决定何时停止打印数字,它们不需要在最短时间内停止打印”。只要在再次解析时可以得到相同的浮点值,库就完成了它的工作


如果您希望看到完全相同的十进制字符串,可以通过适当的格式选项来实现这一点。

它们的值完全相同,只是它们的字符串表示不同。它是相同的数字,只是四舍五入到不同的位数。你的问题到底是什么?“若泽,是的,我没有注意到,谢谢你的C++代码违反了严格的别名BTW(因此是根据标准的未定义行为)。对,你可能想编辑这个问题,使之更加清楚。听起来好像您认为转换为
浮点值的结果在不同的平台上会产生不同的结果。@Martin这里没有转换发生
100001000010110110000001011111和
34.844478607177734375都是完全相同的浮点,只是表示形式不同。如果我将其打印为
0x420b60bf
也不会发生转换。@Martin只是调试器显示了一些东西并不意味着它是真的。对于所有你知道的,调试器使用完全相同的函数来“打印”该值作为用户代码。@马丁:完全合理地考虑“在调试器中显示”为“打印功能”,IMO.。这里的答案是断言值是相同的,而转换为文本形式是这里的区别,而不是“二进制浮动在这个问题上,皈依被断言。另一个例子是吹毛求疵的人为了炫耀自己的聪明才智而对一条无辜的评论吹毛求疵。干得好,你们都很聪明,指出了一些和我说的无关的东西said@Martin当两个人以同样的方式独立地误解你时,你应该考虑到你可能不清楚。在我看来,这仍然是一个将浮点数转换为文本表示的问题,这就是问题所在,这也是这个答案所说的。你还相信答案不对吗?(如果你的意思不是我在第一条评论中认为你的意思,那么我仍然不知道你的意思。)
int a = 1108041919; //The number that is being represented
float f = *(float *)&a;