首页 > 教育培训

java浮点数运算不精确的原因 float和double区别?

float和double区别?

浮动的解释:

动词(verb的缩写)飘,飘;漂泊,飘动;漂移;安排(贷款)被提出来考虑(一个想法或计划);发行(股票)上市;自由浮动(货币汇率)

零钱(用于酒吧等给顾客找钱);飘,飘;浮板;漂浮物;鱼漂;浮动;冰淇淋饮料;浮动期;坐在漂浮的盒子里(为了治疗、康复或放松);救生圈

java浮点数运算不精确的原因 float和double区别?

双重解释:

双倍;配对;(指花)有重瓣的;对于两个人来说;两倍

非常相似的对应物;身体替身;两个人的东西;双倍;(复数)双打,尤指网球;双料冠军(同一赛季或同一年度两次夺冠者);(棒球)双重打击;双精度浮点数(在c语言中)

动词(v

java和c#最大的不同是什么?

我觉得除了语法,最重要的是对底层的掌控能力不同。

虽然c#一开始借鉴了java,但其目的根本不是为了构建一个更好的java,而是为了构建一个更好的c,游戏引擎更喜欢c#就是这个原因。

例如,在c#中可以做什么:

上面的代码会输出10,为什么?因为数组的长度。net存储在数组第一个元素之前的8字节内存中。如果您随后输出*(long*)p-2),您将直接获得该对象的typehandle地址:

然后拿着这个指针,就可以访问对象的methodtable了。

此外,您可以在堆栈上手动分配空间:

然后,您希望绕过gc,直接手动分配堆内存:

以上调用相当于c语言中你调用的malloc,此外还有allocaligned,realloc,alloczeroed等等,可以直接控制内存对齐。

接下来,您希望创建一个具有显式内存布局的结构foo:

那么你就成功模拟了c的一个并集,之所以会有上面的输出,是因为单精度浮点数1的二进制表示是0x01111111000000000000000000000000,在小终端模式存储后占用了4个字节,分别是0x000000000000、0x00000000000、0x000000000。

此外,您可以直接从内存数据构造对象,而无需任何复制开销:

甚至像这样:

从堆内存中创建自然很好:

再比如,此时你有一个用c写的库,里面有这样一段代码:

然后我们编写下面的c#代码:

上面的代码做了什么?我们把c#的函数指针传入c代码,然后在c端调用c#函数。数字生成一个字符串wwwww,然后把这个字符串返回给c#端。它不使用委托而不是函数指针并不重要,因为函数指针在。网。

即使我们没有。;我不想要。net要导入foo.dll,而我们想自己决定动态库的生命周期,我们也可以写:

以上都不是特定于windows和导入的。所以还有。linux和macos上的dylib是完全不可能的。

此外,我们有一些数据,我们想计算,但我们想使用simd进行处理,所以我们只需要写:

您可以看到在x86平台上生成了什么代码:

平台判断的分支会被jit自动淘汰。但实际上,除了手动编写simd代码,前两个分支完全可以省略,只剩下:

因为在这个阶段,当循环边界条件是向量长度时,。net会自动为我们做定向量化,扩展循环。

然后继续,我们还有ref,in和out来传递引用。

假设我们有一个大的struct,为了避免传递时的复制,我们可以直接使用in进行只读引用传递:

对于小型结构,为。net有特殊的优化来帮助我们完全消除内存分配,并将结构完全放在寄存器中,如下面的代码:

上面的代码getdistance被认为是一个热路径,所以我添加了它来指示jit有保证地内联这个函数,最后生成了下面的代码进行测试:

整个过程没有访问内存的指令,效率非常高。

我们也可以借用ref的引用语义来做就地更新:

它甚至可以用于指针和手动分配内存:

与java不同,c#中的泛型真正专门化了所有的类型参数(虽然运行时分布用于引用类型的共享实现),这意味着性能可以得到最大程度的保证,对应的类型根据类型参数的大小有专门的内存布局。还是上面的点例子,我们将下面的数据int替换为泛型参数t,并对值类型number进行泛型约束:

无论是test1还是test2,生成的代码都很优秀,不仅没有打包和解包,而且没有访问操作:

然后,我们有时为了高性能想暂时中止gc恢复,就一句简单的话:

如果你还能分配128mb的内存,你可以告诉gc不要回收,然后一段时间后,即使我们在这个预算中分配内存,也不会发生gc。它甚至可以防止在内存分配不足时阻塞完全垃圾收集:

代码执行完毕,最后一次调用a:

可以恢复。gc行为。

此外,我们还可以指定gc在运行时的模式,以最大限度地提高性能:

此外,我们甚至可以直接在堆内存中执行代码,创建一个jit。net中,直接从内存中创建一个可执行区,然后在其中插入一段代码来添加两个32位整数:

除此之外,c#还有无数底层的编写方法与操作系统交互,甚至使用c#的编译器解除与自身标准库的链接,直接从0开始构建基本类型,然后通过nativeaot编译出完全无gc、可以在裸机硬件上执行引导系统的efi固件也是没有问题的。

另外还有ilgpu可以让你直接在gpu上运行c#代码,在嵌入式设备上运行可以直接操作i2c、pwm、gpio等。,所以不再举例。

而c#已经进入了roadmap的后续更新:允许引用字段的声明,增加类型表示定长内存,允许传递数组时消除数组分配,允许栈上任何对象的分配等等。,所有这些都在改善这些基础性能设施。

那个这是我认为c#和java最大的区别。

在c#中,当你不t需要这些东西,它们好像从来不存在,允许动态类型,不断吸收各种功能特性,各种语法糖加持。简单性和灵活性。;甚至不会失去python,所以你可以愉快而简单地编写各种代码。一旦你需要,你就可以拥有从上到下几乎完全的控制能力,而这些能力会让你在必要的时候不用思考各种奇怪的变通方法,直接把机器榨干,达到c和c的性能,甚至因为运行时pgo而超过c和c的性能。

内存代码类型

原文标题:java浮点数运算不精确的原因 float和double区别?,如若转载,请注明出处:https://www.bjtdsx.com/tag/20646.html
免责声明:此资讯系转载自合作媒体或互联网其它网站,「天地水秀」登载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述,文章内容仅供参考。