声明float,为什么默认类型为double?

2023-12-02

我很好奇为什么浮点文字必须这样声明:

float f = 0.1f;

代替

float f = 0.1;

为什么默认类型是 double,为什么编译器不能通过查看赋值的左侧推断出它是 float?谷歌只给出了默认值的解释,而不是为什么会这样。


为什么默认类型是 double?

这个问题最好问 Java 语言的设计者。他们是唯一知道真相的人real做出该语言设计决定的原因。但我预计其推理大致如下:

他们需要区分这两种类型的文字,因为从数学角度来看,它们实际上意味着不同的值。

假设他们将“float”设置为文字的默认值,请考虑这个示例

// (Hypothetical "java" code ... )
double d = 0.1;
double d2 = 0.1d;

上式中,d and d2实际上会有不同的值。第一种情况,精度较低float值转换为更高的精度double赋值时的值。但你无法恢复不存在的精度。

I posit这两个语句都是合法的,并且含义不同的语言设计是一个坏主意……考虑到第一个语句的实际含义与“自然”含义不同。

按照他们的做法:

double d = 0.1f;
double d2 = 0.1;

都是合法的,但含义又不同。但在第一个语句中,程序员的意图是明确的,而第二个语句的“自然”含义是程序员得到的。在这种情况下:

float f = 0.1f;
float f2 = 0.1;    // compilation error!

...编译器发现不匹配。


我猜测使用浮点数是例外,而不是现代硬件的规则(使用双精度数),因此在某些时候,假设用户在写入时打算使用 0.1f 是有意义的float f = 0.1;

They could已经这样做了。但问题是要提出一组有效的类型转换规则……并且足够简单,您不需要 Java 学学位就可以真正理解。拥有0.1在不同的上下文中表示不同的事物会令人困惑。并考虑一下:

void method(float f) { ... }
void method(double d) { ... }

// Which overload is called in the following?
this.method(1.0);

编程语言的设计很棘手。一个领域的变化可能会对其他领域产生影响。


UPDATE解决@supercat提出的一些问题。

@supercat:考虑到上述重载,方法(16777217)将调用哪个方法?这是最好的选择吗?

我错误地评论了...编译错误。其实答案是method(float).

JLS 是这样说的:

15.12.2.5。选择最具体的方法

如果多个成员方法既可访问又适用于一个 方法调用时,需要选择一个来提供 运行时方法调度的描述符。 Java编程 语言使用选择最具体方法的规则。

...

[符号m1和m2表示适用的方法。]

[如果] m2 不是通用的,并且 m1 和 m2 适用于strict or 松散调用,其中 m1 具有形式参数类型 S1, ..., Sn m2 具有形参类型 T1, ..., Tn,类型 Si 更多 对于所有 i (1 ≤ i ≤ n, n = k),参数 ei 比 Ti 更具体。

...

上述条件是一种方法的唯一情况 可能比另一个更具体。

对于任何表达式,如果 S <: t s>

在这种情况下,我们正在比较method(float) and method(double)这两者都适用于呼叫。自从float <: double, it is 更具体,因此method(float)将被选中。

@supercat:这种行为可能会导致问题,例如一种表达 喜欢int2 = (int) Math.Round(int1 * 3.5) or long2 = Math.Round(long1 * 3.5)被替换为int1 = (int) Math.Round(int2 * 3) or long2 = Math.Round(long1 * 3)

这种变化看起来无害,但前两个表达式是 纠正至613566756 or 2573485501354568和后两个 以上失败5592405[上面最后一个完全是假的715827882].

如果你谈论的是一个做出这种改变的人……嗯,是的。

但是,编译器不会在您背后进行更改。例如,int1 * 3.5有类型double (the int被转换为double),所以你最终调用Math.Round(double).

作为一般规则,Java 算术会隐式地从“较小”​​数字类型转换为“较大”数字类型,但不会从“较大”数字类型隐式转换为“较小”数字类型。

但是,您仍然需要小心,因为(在您的舍入示例中):

  • 整数和浮点数的乘积可能无法以足够的精度表示,因为(比如说)float精度位数比int.

  • 铸造结果Math.round(double)转换为整数类型可以导致转换为整数类型的最小/最大值。

但所有这些都表明,编程语言中的算术支持是很棘手的,对于新的或粗心的程序员来说,不可避免地会遇到一些问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

声明float,为什么默认类型为double? 的相关文章

随机推荐

  • YouTube 嵌入:如何在 Android 版 Chrome 中启用*非静音*自动播放

    这个问题基本上与this one它有一个针对 HLTML5 视频的解决方案 除了更改chrome flags to set gesture requirement for media playback to disabled对 YouTub
  • chrome.webRequest redirectUrl,URL 保存在 chrome.storage.local 中

    我试图拦截网络请求并将它们重定向到我保存在本地存储上的网址 但它不起作用 我的代码如下 chrome webRequest onBeforeRequest addListener function details if details ur
  • 没有工作数据库连接的 Django 管理命令

    我有许多使用以下配置模型的项目 settings py包括默认配置和配置规范 主要用于开发目的 默认设置 包括数据库设置 可以被外部配置文件覆盖 这些文件通常由管理员为其管理的各种环境定义 为了方便管理员 我写了一个管理命令并单独打包 其中
  • 通过 openFileDialog 打开 Web 文件夹 (Sharepoint 2007)

    我有以下用 C 编写的代码片段 openFileDialog1 InitialDirectory fwm storage users curUser My Documents My Pictures openFileDialog1 Filt
  • 在c中编写函数指针

    最近在看一段代码 发现函数指针的写法是 int fn pointer this args this args 我通常会遇到这样的函数指针 return type fn pointer arguments 类似的事情正在讨论here this
  • GTK+ 中的六边形按钮

    我正在尝试创建一个按钮GTK 其形状为六边形 我怎样才能做到不使用CSS 更一般地说 我如何创建我想要的任何形状的按钮 是否可以做这样的事情Glade GTK 的用户界面编辑器 当我发表评论时 我是在虚张声势 因为我从未做过圆形按钮 我只是
  • 将相似的字符串分组

    我正在尝试分析一堆搜索词 数量太多 单独来看并不能说明什么 也就是说 我想对这些术语进行分组 因为我认为相似的术语应该具有相似的有效性 例如 Term Group NBA Basketball 1 Basketball NBA 1 Bask
  • 批处理脚本告诉我最后一次访问文件是什么时候

    我的文件夹中有一个销售订单列表 我想要一个批处理脚本 它可以输出到 txt 文件 所有文件最后一次访问但不一定被修改的时间是什么时候 在 NTFS 文件系统的分区上 有 3 个文件日期 创建日期 上次修改日期和上次访问日期 命令 dir p
  • 将 SID 转换为名称

    我的 Delphi 2010 应用程序需要将 Windows 用户添加到本地管理员组 我使用 NetLocalGroupAddMembers 使这部分工作 现在 该应用程序需要在具有其他语言的本地化版本的 Windows 中运行 为此 我使
  • 如何从新的 Firebase 存储下载和查看图像?

    我可以将图像上传到 Firebase Storage 但下载它们时遇到问题 这是我下载图像的代码 let storage FIRStorage storage let localURL NSURL NSURL string file Doc
  • 以“原始”./2 格式显示列表

    是否可以以 2 格式显示 Prolog 列表 例如 对于列表 L a b c L a b c yes 有没有办法显示 L a b c 通常情况下 write canonical List or write term List quoted
  • 切换多个音频播放/暂停

    我的 HTML CSS 和 JS 都包含在它们自己的文件中 index html javascript js style css 我想更改按钮的背景图像来表示其状态 以下是我当前的片段
  • 在子级中的单击事件(触发函数)之后,将值从子级传递到父级

    In
  • CV:MATLAB 和 OpenCV 相机标定技术之间的差异

    我使用 OpenCV 和 MATLAB 校准了带有棋盘图案的相机 我有 489 and 187分别用于 OpenCV 和 MATLAB 中的平均重投影误差 从表面上看 MATLAB更精确 但我的顾问认为 MATLAB 和 OpenCV 使用
  • JavaScript 中 Math.pow() 在不同浏览器中的奇怪结果

    也许这只发生在 chrome 最新版本中 一些奇怪的行为负指数值仅在Chrome浏览器 我已经检查过不同的浏览器并发现它很奇怪 作为FireFox Chromium将显示完全相同的结果Chrome 最新版本对于某些示例将显示不同的结果 而且
  • 热切加载 List 导航属性

    使用 EF Code First 并给定一个包含列表的实体 我如何快速加载该实体的整个对象图 Example public class Foo public int Id get set public List
  • 如何使用 BadgeDrawable 在汉堡导航菜单图标上添加徽章?

    I add Badge在像这样的按钮上this way 我想添加Badge on hamburger navigation菜单图标用这种方式 但我不知道如何 我找到了一些解决方案 但没有用BadgeDrawable 这是我的代码 但结果不是
  • 如何通过名称获取对 Kotlin 对象的引用?

    如果我有一个顶级对象声明 package com example object MyObject 我怎样才能转换字符串com example MyObject进入参考MyObject 如果你有kotlin reflect在类路径上然后你可以
  • Visual Studio 2010 安装项目 64 位创建注册表项问题

    我有一个 64 位安装项目 其中包含 64 位 Windows 服务 exe 和 dll 在我的安装程序类中 我使用以下代码创建注册表项 using typeKey typeKey CreateSubKey SOFTWARE Folder
  • 声明float,为什么默认类型为double?

    我很好奇为什么浮点文字必须这样声明 float f 0 1f 代替 float f 0 1 为什么默认类型是 double 为什么编译器不能通过查看赋值的左侧推断出它是 float 谷歌只给出了默认值的解释 而不是为什么会这样 为什么默认类