当前位置: 首页 > 面试题库 >

在下面的代码中从int转换为float时,为什么会有价值损失?

白弘伟
2023-03-14
问题内容
int value1 = 123456789;
float value2 = value1;
System.out.println(value1);
System.out.println(value2);

输出:

123456789
123456792


问题答案:

float类型使用与int(32位)相同的位数表示比int仅表示整数更大范围的浮点数。

这会导致精度下降,因为并非每个int数字都可以用来精确表示float。仅24位用于表示数字的小数部分(包括符号位),而其他8位用于表示指数。

如果将此int值分配给double,则不会有任何精度损失,因为它double具有64位,并且其中32个以上的位用于表示小数。

这是更详细的说明:

123456789作为int的二进制表示形式是:

00000111 01011011 11001101 0001 0101

使用以下公式从其32位构造一个单精度浮点数:

(-1)^sign * 1.b22 b21 ... b0 * 2^(e-127)

sign最左边的位在哪里(b31)。b22到b0是小数位,而b30到b23位构成指数e。

因此,将int123456789 转换为时float,只能使用以下25位:

00000111 01011011 11001101 00010101
-    --- -------- -------- -----

我们可以安全地摆脱任何前导零(符号位除外)和任何尾随零。这使您剩下3个最低有效位,我们必须将其删除。我们可以减去5得到123456784:

00000111 01011011 11001101 00010000
-    --- -------- -------- -----

或加3得到123456792:

00000111 01011011 11001101 00011000
-    --- -------- -------- -----

显然,加3可以得到更好的近似值。



 类似资料:
  • 问题内容: 我想将转换成斯威夫特。像这样的基本转换不起作用,因为这些类型不是基元,这与Objective-C中的s和s 不同 但这会产生以下错误消息: “浮点数”不可转换为“整数” 知道如何将属性从转换为吗? 问题答案: 您可以转换到斯威夫特这样的: 您还可以使用@paulm的注释来实现此结果:

  • 问题内容: 我试图将long值传递给该方法,并在那里使用它来创建Long Array。但是,在创建数组时,出现“可能从long到int的有损转换”错误 尽管我还没有使用任何整数值。 问题答案: 数组维只能是类型。编译器期望使用该类型,但是您要传递一种类型。您可以更改传递给的参数类型,并进行相应的更改。 为了完整起见,这是JLS关于数组变量的内容 它们由使用非负 整数 索引值的数组访问表达式引用。

  • 问题内容: 我将从3个简单的示例开始: 所有这些都是预期的。这是一个更复杂的示例。 也符合预期。但是,如果我 每个@unutbu的答案 熊猫正尝试将其重铸为原始dtype。我以为,也许我演奏过的组并没有真正地进行分组。所以我尝试了这个例子来测试这个想法。 我会和。如果@unutbu是正确的,则这些和应该是和,并且可以强制转换为,因此我们应该看到 果然… 但是,如果过程相同但值略有不同。 学过的知识

  • 我试图在Textpad中复制这个Java程序,但我收到以下错误 C:\Users\User\Desktop\java\Drawing.java:14: 错误: 不兼容的类型: 从 float 到 int g.drawLine ((getWidth()/2) , 0, (getWidth()*i) , (getHeight()/2)); 这是代码 在getWidth*i之前我已经尝试过添加(floa

  • 我想在Swift中将转换为。像这样的基本强制转换不起作用,因为这些类型不是原语,不像Objective-C中的s和s

  • 问题内容: 在Go中,有可能等同于或取决于系统架构的类型。我可以声明一个整数变量而不必担心它的大小: 为什么没有type ,它等于或取决于我的系统的体系结构?我希望我也可以: 问题答案: float已在版本2011/01/20中删除。 您仍然可以使用简短的变量声明: 但正如GO常见问题解答所述: 出于可移植性的原因,我们决定以代码中的一些显式转换为代价,使事情变得清晰明了。 您可以在以下主题中查看